Thread overview
OT: What causes the Segfault in the following?
Aug 04, 2017
Andrew Edwards
Aug 04, 2017
Andrew Edwards
Aug 04, 2017
Andrew Edwards
Aug 04, 2017
Andrew Edwards
Aug 04, 2017
Ali Çehreli
Aug 04, 2017
Andrew Edwards
Aug 04, 2017
Andrew Edwards
Aug 04, 2017
Kagamin
August 04, 2017
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.
August 04, 2017
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
August 03, 2017
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

August 03, 2017
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
August 04, 2017
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.
August 03, 2017
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
August 04, 2017
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
>

August 04, 2017
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.
August 04, 2017
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.
August 04, 2017
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.