www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - OT: What causes the Segfault in the following?

reply Andrew Edwards <edwards.ac gmail.com> writes:
int main()
{
     //int wierd[4];
     struct nk_color str = nk_rgba_hex("#deadbeef");
     //int wierd[4];
     char *s;
     //int wierd[4];
     nk_color_hex_rgb(s, str);
     //int wierd[4];
     printf("(%d,%d,%d)\n",str.r, str.g, str.b);
     //int wierd[4];
     printf("%s\n", s);
     //int wierd[4];
     return 0;
}

The above produces as its output:

(222,173,190)
DEADBE

but if I introduce an int array on any of the commented lines, it 
results in a runtime Segmentation fault: 11. Basically I'm just trying 
to port Nuklear[1] to D as a first project after reading Ali and Mike's 
awesome books. Moving one function at a time to an independent C file, 
compiling it to observe the result and then from the understanding 
gained, re-implementing it in D. The int array here is introduced to 
prepare for port of the next function and has nothing to do with the 
current content of main(), but I'm completely confused because I don't 
see anything wrong with the code that is causing the error.

By the way, the program responds differently based on the type of the array:

	double => Bus error: 10
	char => no error
	short => Segmentation fault: 11
	long => Bus error: 10

Obviously I'm missing something... please enlighten me.

Thanks,
Andrew

[1] Yes, I know there is already a port and bindings available... this 
is purely for learning. My goal is actually to port imgui for a project 
I committed myself to at DConf2017 but in the process of doing so, I 
realized how woefully inadequate my knowledge of programming is. This is 
my attempt at rectifying the situation.
Aug 03
next sibling parent reply Andrew Edwards <edwards.ac gmail.com> writes:
Andrew Edwards wrote:
 int main()
 {
     //int wierd[4];
     struct nk_color str = nk_rgba_hex("#deadbeef");
     //int wierd[4];
     char *s;
     //int wierd[4];
     nk_color_hex_rgb(s, str);
     //int wierd[4];
     printf("(%d,%d,%d)\n",str.r, str.g, str.b);
     //int wierd[4];
     printf("%s\n", s);
     //int wierd[4];
     return 0;
 }

 The above produces as its output:

 (222,173,190)
 DEADBE

 but if I introduce an int array on any of the commented lines, it
 results in a runtime Segmentation fault: 11. Basically I'm just trying
 to port Nuklear[1] to D as a first project after reading Ali and Mike's
 awesome books. Moving one function at a time to an independent C file,
 compiling it to observe the result and then from the understanding
 gained, re-implementing it in D. The int array here is introduced to
 prepare for port of the next function and has nothing to do with the
 current content of main(), but I'm completely confused because I don't
 see anything wrong with the code that is causing the error.

 By the way, the program responds differently based on the type of the
 array:

     double => Bus error: 10
     char => no error
     short => Segmentation fault: 11
     long => Bus error: 10

 Obviously I'm missing something... please enlighten me.

 Thanks,
 Andrew

 [1] Yes, I know there is already a port and bindings available... this
 is purely for learning. My goal is actually to port imgui for a project
 I committed myself to at DConf2017 but in the process of doing so, I
 realized how woefully inadequate my knowledge of programming is. This is
 my attempt at rectifying the situation.
Just in case... here are the two functions being called in main(): https://github.com/vurtun/nuklear/blob/master/nuklear.h#L5695-L5722
Aug 03
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/3/17 9:12 PM, Andrew Edwards wrote:
 Andrew Edwards wrote:
 int main()
 {
     //int wierd[4];
     struct nk_color str = nk_rgba_hex("#deadbeef");
     //int wierd[4];
     char *s;
     //int wierd[4];
     nk_color_hex_rgb(s, str);
     //int wierd[4];
     printf("(%d,%d,%d)\n",str.r, str.g, str.b);
     //int wierd[4];
     printf("%s\n", s);
     //int wierd[4];
     return 0;
 }

 The above produces as its output:

 (222,173,190)
 DEADBE

 but if I introduce an int array on any of the commented lines, it
 results in a runtime Segmentation fault: 11. Basically I'm just trying
 to port Nuklear[1] to D as a first project after reading Ali and Mike's
 awesome books. Moving one function at a time to an independent C file,
 compiling it to observe the result and then from the understanding
 gained, re-implementing it in D. The int array here is introduced to
 prepare for port of the next function and has nothing to do with the
 current content of main(), but I'm completely confused because I don't
 see anything wrong with the code that is causing the error.

 By the way, the program responds differently based on the type of the
 array:

     double => Bus error: 10
     char => no error
     short => Segmentation fault: 11
     long => Bus error: 10

 Obviously I'm missing something... please enlighten me.

 Thanks,
 Andrew

 [1] Yes, I know there is already a port and bindings available... this
 is purely for learning. My goal is actually to port imgui for a project
 I committed myself to at DConf2017 but in the process of doing so, I
 realized how woefully inadequate my knowledge of programming is. This is
 my attempt at rectifying the situation.
Just in case... here are the two functions being called in main(): https://github.com/vurtun/nuklear/blob/master/nuklear.h#L5695-L5722
Can you show how you declared these in D? It's important. I think what's happening is that the nk_color_hex_rgb is incorrectly defined. I think you should *always* get segfault, with or without any of those arrays. -Steve
Aug 03
parent reply Andrew Edwards <edwards.ac gmail.com> writes:
Steven Schveighoffer wrote:
 On 8/3/17 9:12 PM, Andrew Edwards wrote:
 Andrew Edwards wrote:

 Just in case... here are the two functions being called in main():

 https://github.com/vurtun/nuklear/blob/master/nuklear.h#L5695-L5722
Can you show how you declared these in D? It's important. I think what's happening is that the nk_color_hex_rgb is incorrectly defined. I think you should *always* get segfault, with or without any of those arrays. -Steve
I certainly can, but the problem is completely in C, I'm not having any problems in D. In this case, I've simply copied the two functions to test.c and inserted main(). Here are my implementations though: nk_color nk_rgb_hex(string rgb) { if (rgb[0] == '#') rgb = rgb[1..$]; return nk_color(cast(nk_byte)nk_parse_hex(rgb[0 .. 2]), cast(nk_byte)nk_parse_hex(rgb[2 .. 4]), cast(nk_byte)nk_parse_hex(rgb[4 .. $]), 255); } private void nk_color_hex_impl(int n)(out char[] output, nk_color col) { output.reserve(n); alias NK_TO_HEX = (i) => i <= 9 ? '0' + i : 'A' - 10 + i; foreach(color; col.tupleof) { output ~= to!char(NK_TO_HEX((color & 0xF0) >> 4)); output ~= to!char(NK_TO_HEX(color & 0x0F)); } } void nk_color_hex_rgba(out char[] output, nk_color col) { nk_color_hex_impl!8(output, col); } void nk_color_hex_rgb(out char[] output, nk_color col) { nk_color_hex_impl!6(output, col); } Not to happy with nk_color_hex_impl and family yet because I'm convinced there is a better way but for now that's what I've got.
Aug 03
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 8/3/17 10:14 PM, Andrew Edwards wrote:
 Steven Schveighoffer wrote:
 On 8/3/17 9:12 PM, Andrew Edwards wrote:
 Andrew Edwards wrote:

 Just in case... here are the two functions being called in main():

 https://github.com/vurtun/nuklear/blob/master/nuklear.h#L5695-L5722
Can you show how you declared these in D? It's important. I think what's happening is that the nk_color_hex_rgb is incorrectly defined. I think you should *always* get segfault, with or without any of those arrays.
I certainly can, but the problem is completely in C, I'm not having any problems in D. In this case, I've simply copied the two functions to test.c and inserted main().
Oh. Then Ali is correct. I assumed that char *s was initialized to null because it was D, and maybe you were passing s by reference incorrectly. But actually, you are in c, so s can point anywhere. Yeah, you need to declare an array instead of just a pointer. char s[20] should work. -Steve
Aug 03
parent Andrew Edwards <edwards.ac gmail.com> writes:
Steven Schveighoffer wrote:
 On 8/3/17 10:14 PM, Andrew Edwards wrote:
 I certainly can, but the problem is completely in C, I'm not having
 any problems in D. In this case, I've simply copied the two functions
 to test.c and inserted main().
Oh. Then Ali is correct. I assumed that char *s was initialized to null because it was D, and maybe you were passing s by reference incorrectly. But actually, you are in c, so s can point anywhere. Yeah, you need to declare an array instead of just a pointer. char s[20] should work. -Steve
Much appreciated.
Aug 03
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 08/03/2017 06:02 PM, Andrew Edwards wrote:

     char *s;
That's an uninitialized C string.
     nk_color_hex_rgb(s, str);
That function is expecting it to have at least 7 chars when doing things like output[1] = (char)NK_TO_HEX((col.r & 0x0F)); So you have to have a proper pointer to the first element of an array to pass to nk_color_hex_rgb. The following may work but you shouldn't be needing to use magic constants like 7: char[7] s; nk_color_hex_rgb(s.ptr, str); // ... printf("%s\n", s.ptr); There's probably the proper C macro that defines it so that you can do char[BLAH_LENGTH] s: Ali
Aug 03
next sibling parent Andrew Edwards <edwards.ac gmail.com> writes:
Ali Çehreli wrote:
 On 08/03/2017 06:02 PM, Andrew Edwards wrote:

     char *s;
That's an uninitialized C string.
OK, I was is indeed the problem. I was thinking for some reason that s gets initialized inside nk_color_hex_rgb() but it's expecting to an array to work with. I actually noticed that couldn't, for the life of me, associate it to the cause of the resulting issue.
     nk_color_hex_rgb(s, str);
That function is expecting it to have at least 7 chars when doing things like output[1] = (char)NK_TO_HEX((col.r & 0x0F)); So you have to have a proper pointer to the first element of an array to pass to nk_color_hex_rgb. The following may work but you shouldn't be needing to use magic constants like 7: char[7] s; nk_color_hex_rgb(s.ptr, str); // ... printf("%s\n", s.ptr); There's probably the proper C macro that defines it so that you can do char[BLAH_LENGTH] s: Ali
Aug 03
prev sibling parent reply Andrew Edwards <edwards.ac gmail.com> writes:
Ali Çehreli wrote:
 On 08/03/2017 06:02 PM, Andrew Edwards wrote:

     char *s;
That's an uninitialized C string.
OK, I was is indeed the problem. I was thinking for some reason that s gets initialized inside nk_color_hex_rgb() but it's expecting to an array to work with. I actually noticed that couldn't, for the life of me, associate it to the cause of the resulting issue.
     nk_color_hex_rgb(s, str);
That function is expecting it to have at least 7 chars when doing things like output[1] = (char)NK_TO_HEX((col.r & 0x0F)); So you have to have a proper pointer to the first element of an array to pass to nk_color_hex_rgb. The following may work but you shouldn't be needing to use magic constants like 7: char[7] s; nk_color_hex_rgb(s.ptr, str); // ... printf("%s\n", s.ptr);
got you... this makes sense, but I'm doing it differently in D. See my response to Steven. I was only experiencing this issue in C.
 There's probably the proper C macro that defines it so that you can do

   char[BLAH_LENGTH] s:

 Ali
Much appreciated.
Aug 03
parent Kagamin <spam here.lot> writes:
On Friday, 4 August 2017 at 02:38:10 UTC, Andrew Edwards wrote:
 OK, I was is indeed the problem. I was thinking for some reason 
 that s gets initialized inside nk_color_hex_rgb()
Usually C functions don't allocate memory. And when they do, they do it in unique ways, which is a PITA, that's why the caller is usually responsible for memory management.
Aug 04