检测到堆腐蚀:正常阻塞后

“CRT检测到应用程序写入堆缓冲区的内存末尾”错误。 它到达时会崩溃。 任何帮助表示赞赏。

 int messageFunction(char* message) { char* sPtr = strstr(message,"Subject:"); char* cPtr = strstr(message,"Content:"); char* messageSubject = (char*) malloc(cPtr - sPtr - strlen("Subject:")) char* messageContent = (char*) malloc(strlen(cPtr + strlen("Content:"))) strncpy(messageSubject, stPtr + strlen("Subject:"), cPtr - sPtr - strlen("Subject:")); messageSubject[cPtr - sPtr - strlen("Subject:")] = '\0'; strncpy(messageContent, cPtr + strlen("Content:"), strlen(cPtr + strlen("Content:"))); ... free(messageSubject); free(messageContent); } void main() { char* message = "Subject:HelloWorldContent:MessageContent"; int result = messageFunction(message); } 

您正在分配一个字节太短的内存。 您的计算是针对例如“主题:”和“内容:”之间的数据长度,但不考虑字符串中对空终止符的需要。 然后,当您手动添加空终止符时,您将通过写入数组末尾来调用未定义的行为。

将代码更改为以下内容应该可以解决问题。

 char* messageSubject = malloc(cPtr - sPtr - strlen("Subject:") + 1) char* messageContent = malloc(strlen(cPtr + strlen("Content:")) + 1) 

您也不会在“…”部分显示代码,因此您可能在其中有一个未终止的字符串,如果它正在由字符串库例程处理,则可能会导致问题。

如果你这样做:

 char* v = malloc(n); 

那么v的有效下标范围从v[0]v[n-1] 。 特别是, v [n]永远不会有效 。 这是一般规则。 如果再次查看代码,您应该会看到问题所在。

几个笔记:

  1. 您的代码假定主题:位于内容之前:并且它们都存在。 在某些情况下,这种假设是不正确的。 你应该在开始malloc’ing大量的内存之前检查(因为小的负数变成巨大的正无符号数)。 你还应该确保你的mallocs不会返回0,而不是在它们执行时返回segfaulting。

  2. strdup (和strndup )通常会让你免于尴尬的“哎呀,我没有为NUL字节分配足够的空间”错误。 它们也不需要几乎同样多的未来,使您的代码更简单,更可靠,更容易理解。 了解他们。 他们将是你的朋友。

  3. 如果没有其他工作, valgrind可以帮助您找到这样的错误。