-2

I am trying to understand pointers, and trying to define a structure as follows.

| header info (size_t) | pointer to cstring |

here is part of the code. I type defined string as char**.

string str_constructor(const char* const str)
{
    size_t* header = (size_t*)(malloc(sizeof(size_t) + sizeof(char**)));
    char** data = (char**)(header + 1); //data is now the address of the pointer to cstring
    *data = (char*)(malloc(strlen(str) + 1)); // plus one char for null character
    for (int i = 0; i != strlen(str); i++)
    {
        *data[i] = str[i]; // cstring deep copy
    }
    *header = strlen(str); // store length of string
    *data[*header] = '\0'; // append null character
    return data;
}

The program crashed on 2nd iteration of the for-loop.

Basically I want to define a string, where *string would return the char*.

christopher_pk
  • 641
  • 4
  • 17

2 Answers2

2

The lines look unusual

size_t* header = (size_t*)(malloc(sizeof(size_t) + sizeof(char*)));
char** data = (char*)(header + 1); //data is now the address of the 
                                     pointer to cstring

Why cast the return to size_t*? Why double pointer char **?

I would try something like

struct info {size_t size; char * string};

struct info * p = malloc(sizeof *p);
p->size = strlen(str) + 1;
p->string = strdup(str);
Arun
  • 19,750
  • 10
  • 51
  • 60
2

This is a highly unorthodox way of creating a structure in memory, but if, as you say, you want to understand pointers, then who are we to tell you to do it differently?

The only real problem with the code you posted is that *data[i] = ... should be (*data)[i] = ....

That having been said, you might want to consider that your way of creating a structure in memory ignores the native alignment of the CPU, which means that you are bound to get sub-optimal performance. Declaring a struct would have taken care of that. On some architectures (not x86 luckily) your program may even crash if it attempts to make a non properly aligned memory access.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • I see. I am actually building this function for micro processors, specifically stm32. I suppose I have to ensure it is 8-byte alligned? – christopher_pk Jun 03 '17 at 14:46
  • I know nothing of the stm32. I have never even heard of it before. If the 32 in the name means 32-bit, then you will probably be fine with 4-byte alignment, which is most probably what you get with `header + 1`. However, a) You should read up on it, or b) just try it and see if it works, or c) just play it safe and let the compiler take care of alignment for you so that you do not have to worry about it. I would read up on it and *still* play it safe. – Mike Nakis Jun 03 '17 at 14:49