如何解决malloc()破坏指针的情况?

zw3*_*324 0 c memory malloc pointers corruption

这是我刚才写的函数的简化版本:

int foobar(char * foo) {
  puts(type);
  struct node * ptr = (struct node *) malloc (sizeof(struct node));
  puts(type);
  memset(ptr, 0, sizeof(ptr));
  ptr=head;
  return head->id;
}
Run Code Online (Sandbox Code Playgroud)

这里node只是一个在链表中声明为节点的结构,它包含char *一个指向下一个节点的指针.但是,我意识到malloc()这里正在腐蚀我的输入char * foo.

为什么会malloc()破坏我的输入字符指针?另外,我怎么能在这里解决这个问题?现在我只是将该指针的内容复制到本地数组,但这太过于hacky,即使是我的口味(这不是最好的).

感谢您的任何投入!

编辑:嗯,这是更真实的代码:

void foobar(char * type) {
  puts(type); <-- here it's a long string about 30 char
  struct node * ptr = (struct node *) malloc (sizeof(struct node));
  puts(type); <- chopped of, 10 left with some random thing at the end
}
Run Code Online (Sandbox Code Playgroud)

希望问题现在清楚了!谢谢!

编辑:

这是如何type初始化:

type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);
Run Code Online (Sandbox Code Playgroud)

谢谢!

Jon*_*ler 7

明显的腐败会发生,因为typefoo指向已经释放的内存,这malloc()会给你一个不同的用途.

一旦释放内存,就无法继续使用它.

你也有问题,因为你分配给ptr,然后消除ptr:

ptr = head;
Run Code Online (Sandbox Code Playgroud)

你可能意味着:

head = ptr;
Run Code Online (Sandbox Code Playgroud)

但你可能需要在此ptr->next = head;之前设置.当然,这是猜测,因为你没有显示类型定义.

你为什么换来的却也并不明显head->id的,而不是任何headptr.不幸的是,我们没有足够的信息来说"这错的"; 这不常见.


关于第二编辑的评论

这是类型初始化的方式:

type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);
Run Code Online (Sandbox Code Playgroud)

有一些麻烦.你已经忘记了没有商业践踏的记忆.

前两行很好; 你复制一个字符串.但是请注意,这type是指向6个字节内存tempType的指针,并且是指向7个字节内存的指针.

灾难发生在第三线.

type + strlen(type)指向type字符串末尾的空字节.然后你tempType或多或少合法地写1个字节; 你不再有一个空终止的字符串,但第一个字节在边界内.第二个和后续字节写在未分配给您的空间中,并且可能包含有关内存分配的控制信息.

写出已分配的内存的边界会导致"未定义的行为".任何事情都可能发生.在某些机器上,特别是使用64位编译时,您可能会完全放弃它.在大多数机器上,特别是32位编译中,你已经破坏了你的堆内存,某些地方(通常距离这个地方有点远)会因此而遇到麻烦.这是记忆滥用的本质; 它出现的地方似乎经常起作用,而且其他一些无辜的代码遭受其他地方引起的问题.

所以,如果你想连接这些字符串,你需要做类似的事情:

char *type = strdup("Some ");
char *tempType = strdup("things");
char *concat = malloc(strlen(type) + strlen(tempType) + 1);
sprintf(concat, "%s%s", type, tempType);
Run Code Online (Sandbox Code Playgroud)

我省略了错误检查.您应该检查分配,strdup()malloc()确保分配内存.有些人可能会说你应该使用snprintf(); 这是一个有意识的决定不这样做,因为我已经计算了前一行中的必要空间并分配了足够的空间.但你至少应该考虑它.如果您还没有确保有足够的可用空间,那么您应该使用snprintf()以避免缓冲区溢出.您还可以检查其返回值,以便了解信息是否全部格式化.(另请注意,您有3个指向free的指针,或者传递给其他代码,以便在适当的时间释放分配的内存.)

请注意,在Windows上,snprintf()(或_snprintf())的行为方式与C99标准不同.坦率地说,这没有用.


Ada*_*iss 5

我不确定你要做什么,但评论表明发生了什么:

// This allocates enough memory for a struct node and assigns it to ptr.
struct node * ptr = (struct node *) malloc (sizeof(struct node));

// This displays the data in the (unspecified) string type,
// which must be null terminated.
puts(type);

// This sets the first 4 bytes of ptr to 0, assuming pointers are 4 bytes.
// You probably want memset(ptr, 0, sizeof(struct node));
memset(ptr, 0, sizeof(ptr));

// This makes ptr point to the address of head, orphaning the memory
// that was just malloc'ed to ptr.
ptr=head;
Run Code Online (Sandbox Code Playgroud)