This c program gives a segmentation fault

I am write a c program to test structure pass into a function

but it give segmentation fault ,why?

please give me the solution to solve this issue?

The code i am tried is given below,

#include <stdio.h>

#include <string.h>

#define GRAYSCALE
void set_pixel_data(int depth, void   *p);
   
struct pixel_gray { char m; };
struct pixel_color { char r; char g; char b; };


int main()
{
struct pixel_gray  pg;
struct pixel_color pc;
#ifdef GRAYSCALE
	set_pixel_data( 1, &pg);
#else
	set_pixel_data( 3, &pc);
#endif

	return(0);
}
void set_pixel_data(int depth, void   *p)
{

switch(depth)
{
struct pixel_gray* p1;
case 1:
p1=(struct pixel_gray*)p;
strcpy(p1->m,"s");                                   //here is the problem
//printf("%s",p1->m);


    break;
case 3:
    printf("33");
    break;
default:
    printf("nothing he he ");
    break;
}

}

When you encounter an error you'll see a button on the right side of the orange bar in the Arduino IDE "Copy error messages" (or the icon that looks like two pieces of paper in the Arduino Web Editor). Click that button. Paste the error in a reply here using code tags.

If the text exceeds the forum's 9000 character limit, save it to a .txt file and post it as an attachment. If you click the "Reply" button here, you will see an "Attachments and other settings" link.

      strcpy(p1->m, "s");                                  //here is the problem

m is a char. why are you trying to copy a full cString into it. just do

     p1->m = 's';                  //and this problem goes away

if you want a local temporary pointer just to provide the type in each case, you'll need to put {} around your case.

  switch (depth) {
    case 1:
      {
        struct pixel_gray* p1 = (struct pixel_gray*)p;
        p1->m = 's';
      }
      break;
      ....
  }

but you don't need really the struct pixel_gray* p1, just cast your void* to the right type depending on the case value.

#include <stdio.h>
#include <string.h>
//#define GRAYSCALE

void set_pixel_data(int depth, void   *p);

struct pixel_gray {
  char m;
};

struct pixel_color {
  char r;
  char g;
  char b;
};


int main()
{
#ifdef GRAYSCALE
  struct pixel_gray  pg;
  set_pixel_data( 1, &pg);
#else
  struct pixel_color pc;
  set_pixel_data( 3, &pc);
#endif
  return (0);
}

void set_pixel_data(int depth, void* p)
{
  switch (depth) {
    case 1:
      ((struct pixel_gray*)p)->m = 's';
      break;
    case 3:
      ((struct pixel_color*)p)->r = 'r';
      ((struct pixel_color*)p)->g = 'g';
      ((struct pixel_color*)p)->b = 'b';
      break;
  }
}

and you don't need the switch at all, put conditional code based on the value of #ifdef GRAYSCALE

#include <stdio.h>
#include <string.h>
//#define GRAYSCALE

void set_pixel_data(void   *p);

struct pixel_gray {
  char m;
};

struct pixel_color {
  char r;
  char g;
  char b;
};


int main()
{
#ifdef GRAYSCALE
  struct pixel_gray  pg;
  set_pixel_data(&pg);
#else
  struct pixel_color pc;
  set_pixel_data(&pc);
#endif
  return (0);
}

void set_pixel_data(void* p)
{
#ifdef GRAYSCALE
  ((struct pixel_gray*)p)->m = 's';
#else
  ((struct pixel_color*)p)->r = 'r';
  ((struct pixel_color*)p)->g = 'g';
  ((struct pixel_color*)p)->b = 'b';
#endif
}

and last but not least, are you sure you want to hold characters in the structure? shouldn't a uint8_t be better? (a number fitting on a byte - value between 0 and 255)

thanks alot

wounder1:
thanks alot

you are welcome; I added a few comments above whilst you were responding

You should turn your warning level up to 'All' (in Preferences) so you get useful feedback when your code does something that even the compiler thinks is weird.

Arduino: 1.8.10 (Mac OS X), Board: "Arduino/Genuino Uno"


/Users/john/Documents/Arduino/sketch_nov08a/sketch_nov08a.ino: In function 'int main()'
/Users/john/Documents/Arduino/sketch_nov08a/sketch_nov08a.ino: In function 'void set_pixel_data(int, void*)':
sketch_nov08a:41:18: error: invalid conversion from 'char' to 'char*' [-fpermissive]
       strcpy(p1->m, "s");                                  //here is the problem
              ~~~~^
In file included from /Applications/Arduino1.8.10.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:25:0,
                 from sketch/sketch_nov08a.ino.cpp:1:
/Applications/Arduino1.8.10.app/Contents/Java/hardware/tools/avr/avr/include/string.h:305:14: note:   initializing argument 1 of 'char* strcpy(char*, const char*)'
 extern char *strcpy(char *, const char *);
              ^~~~~~
exit status 1
invalid conversion from 'char' to 'char*' [-fpermissive]