0

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

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;
}

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

为什么会malloc()损坏我的输入字符指针?另外,我该如何解决这里的问题?现在我只是将该指针的内容复制到本地数组,但这太老套了,即使我的口味(这不是最好的)。

感谢您的任何投入!

编辑:好吧,这里有更真实的代码:

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
}

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

编辑:

以下是type初始化的方式:

type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);

谢谢!

4

2 回答 2

7

明显的损坏会发生,因为typefoo指向已经释放的内存,这些内存malloc()会返回给您以供其他用途。

一旦你释放了内存,你就不能继续使用它。

你也有一个问题,因为你分配给ptr,然后ptr用:

ptr = head;

你的意思可能是:

head = ptr;

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

也不清楚为什么你返回head->id而不是heador ptr。不幸的是,我们没有足够的信息说“那错误的”;这不寻常。


第二次编辑的评论

以下是 type 的初始化方式:

type = strdup("Some ");
tempType = strdup("things");
sprintf(type + strlen(type), "%s", tempType);

有一些麻烦。你已经践踏了你没有任何业务践踏的记忆。

前两行很好;你复制一个字符串。但请注意,这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);

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

请注意,在 Windows 上,snprintf()(or _snprintf()) 的行为方式与 C99 标准指定的方式不同。坦率地说,这没有帮助。

于 2012-04-12T01:26:31.987 回答
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;
于 2012-04-12T01:31:12.950 回答