简体   繁体   English

奇怪的char ** / calloc行为

[英]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 . 当我调试以下代码时, strncpy可以正常工作,但是一旦循环退出,我就会看到parent_var_names指向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) . for循环init中的int i(1)可能应该是int i(0)

Otherwise you're never setting parent_var_names[0] to anything other than the 0 that calloc() initializes it to. 否则,您永远不要将parent_var_names[0]设置为calloc()初始化为0以外的任何0

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. 仅出于完整性考虑(因为在注释中多次提到了此问题),您没有考虑要复制的字符串的'\\ 0'终止符。 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. 由于您没有在strncpy()调用中复制终止符,因此不会溢出分配的缓冲区,但结果不是正确终止的字符串。 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. (Microsoft)调试堆的功能是在内存的分配区域周围放置保护字节(即0xFDFDFDFD)。 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). 看到您遇到了该值,或者意味着您正在某个地方覆盖内存,或者您正在查看parent_var_names[0]的值而实际上没有在其中写入任何内容(即仔细查看初始化循环变量i的值)。

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. 还要确保您的markov_parents绝对是零终止的。 Btw., in response to your comment that you want "C and C++ compatibility": Your code is not valid C code, so ... 顺便说一句,响应您的评论,您想要“ C和C ++兼容性”:您的代码不是有效的C代码,因此...

If your parent_var_names aren't NULL terminated it's probably because you are using strlen when you allocate space for the strings. 如果您的parent_var_names不以NULL终止,则可能是因为在为字符串分配空间时使用了strlen This fails to create space for the string and the NULL terminator. 这无法为字符串 NULL终止符创建空间。 Try strlen()+1 instead. 尝试使用strlen()+1代替。

You should probably be using std::string anyway... 无论如何,您可能应该使用std :: string ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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