简体   繁体   中英

Strange char**/calloc behavior

When I debug the following code, strncpy works fine but as soon as the loop exits, I see that parent_var_names is pointing NULL/0xfdfdfddf . I am puzzled!

parent_var_names = (const char**)calloc(net->nodes[x]->num_parents, sizeof(const char*));
for(int i(1); i < net->nodes[x]->num_parents; ++i)
{
  parent_var_names[i] = (const char*)malloc(strlen(rhs_arr[net->nodes[x]->markov_parents[i]]));
  strncpy((char*)parent_var_names[i], (char*)rhs_arr[net->nodes[x]->markov_parents[i]], strlen(rhs_arr[net->nodes[x]->markov_parents[i]]));
}

int i(1) in your for loop init should probably be int i(0) .

Otherwise you're never setting parent_var_names[0] to anything other than the 0 that calloc() initializes it to.

Just for completeness (since this is mentioned a couple times in the comments), you're not taking into account the '\\0' terminator for the strings you're copying. Since you're not copying the terminator in your strncpy() calls, you're not overflowing the buffers allocated, but your results aren't properly-terminated strings. It's possible that this is your intent, but that would be unusual. If it is intended, throw a comment in there...

Placing guard bytes (ie 0xFDFDFDFD) around an allocated region of memory is a feature of the (Microsoft) debug heap. Seeing that you encounter this value either means you are overwriting memory somewhere, or you are looking at the value of parent_var_names[0] without actually writing anything in there (ie take a close look at the value you initialize your loop variable i with).

Furthermore, your code could be simplified to:

#include <string>
/* ... */

int ii = 0;
int parent_count = net->nodes[x]->num_parents;
char** parent_var_names = calloc(parent_count, sizeof(char*));

for(; ii < parent_count; ++ii)
{
    parent_var_names[ii] = strdup(rhs_arr[net->nodes[x]->markov_parents[ii]]);
}

Also make sure your markov_parents are definitely zero-terminated. Btw., in response to your comment that you want "C and C++ compatibility": Your code is not valid C code, so ...

If your parent_var_names aren't NULL terminated it's probably because you are using strlen when you allocate space for the strings. This fails to create space for the string and the NULL terminator. Try strlen()+1 instead.

You should probably be using std::string anyway...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM