C 检测到堆损坏:在正常块之后

C 检测到堆损坏:在正常块之后,c,visual-studio-2010,C,Visual Studio 2010,“CRT检测到应用程序写入堆缓冲区的内存端”错误。它到达空闲时崩溃。感谢您的帮助 int messageFunction(char* message) { char* sPtr = strstr(message,"Subject:"); char* cPtr = strstr(message,"Content:"); char* messageSubject = (char*) malloc(cPtr - sPtr - strlen("Subject:")) char*

“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* v = malloc(n);
那么v的有效下标的范围是从
v[0]
v[n-1]
。特别是,v[n]永远无效。这是一般规则。如果您再次查看代码,就会发现问题所在

几点注意:

  • 您的代码假定主题在内容之前,并且两者都存在。这种假设在某些情况下是不正确的。在开始对大量内存进行malloc'运算之前,应该进行检查(因为小的负数会变成大的正无符号数)。您还应该确保malloc不返回0,而不是在返回0时进行分段故障处理

  • strdup
    (和
    strndup
    )通常会使您避免尴尬的“哎呀,我没有为NUL字节分配足够的空间”错误。它们也不需要太多的推敲,使您的代码更简单、更可靠、更容易理解。了解他们。他们将是你的朋友

  • 如果其他方法都不起作用,
    valgrind
    可以帮助您找到这样的bug


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

    将代码更改为以下应该可以修复它

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

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

    谢谢您,先生,您救了我一天。我将代码从char数组转换为char指针,并错误地保留了数组的长度,该长度必须增加1+1代表+1(空终止符)提示。由于忽略了乘法运算符的优先级,并且将“malloc(count+1*sizeof(char))”更改为“malloc((count+1)*sizeof(char))”确实修复了该错误,谢谢