0

伙计们,我正在生成一个字符串,它表示文件的路径,连接一个宏和一个字符串。功能是这样的:

char *userPath(char *username)
{
   char *path = (char*)malloc(sizeof(char) * (strlen(MAILBOXES) + strlen(username) + 1));
   path[0] = '\0';
   strcat(path, MAILBOXES);
   strcat(path, "/");
   strcat(path, username);
   return path;
}

返回的指针引用了一个正确的字符串,但是在调用这个函数之后,进程抛出了一个非常非常糟糕的* glibc 检测到./mmboxd: malloc(): memory corruption: 0x085310a8 * * with the relative backtrace。我知道问题出在这里,因为我在实现它后就开始遇到这个错误,而且我使用的唯一 malloc 就在这里。这段代码有什么问题?

4

8 回答 8

9

+1 应该是 +2 以考虑您添加的分隔符和空终止符。您可以省略 sizeof(char),它始终为 1。

于 2011-04-28T18:11:47.657 回答
4

这是问题所在:

   char *path = (char*)malloc(sizeof(char) * (strlen(MAILBOXES) + strlen(username) + 1));

您为 a) 中的所有字符MAILBOXES、b) 中的所有字符username和 c)'/'字符分配了足够的内存,但是您忘记了 d) 终止'\0'字符!所以+ 1应该是+ 2

您的代码还有其他一些奇怪之处,但它们并没有错,只是可能会更好:

  1. 您不需要malloc在 C 中强制转换返回值,并且有些人(像我一样)认为它的风格很糟糕,原因有很多,因为您可以使用谷歌搜索。
  2. sizeof(char)始终为 1(这在标准中定义)。有人说要保持对称。有人说把它拿出来,因为它是一个。有人说将其更改为sizeof *path,这样如果您更改path为 a wchar_t *malloc将正确调整以保持分配正确的大小。
  3. 使用strcat将第一位数据写入字符串可能效率低下。为什么不掉线path[0] = '\0';而只使用strcpy第一位数据呢?
  4. 您计算所有字符串的长度,然后将它们扔掉并使用strcat,这将重新遍历(先前计算的)长度以找到正确的位置。如果您存储了两次strlen调用的结果,则无需使用strcat并不必要地不断重新计算字符串末尾的位置。
  5. Using strcat to append a single character is inefficient.
  6. You don't check the return value of malloc for success or failure before you use it.
于 2011-04-28T18:18:54.943 回答
2

您似乎没有为零终止符留出空间。你应该为此分配额外的费用char

我假设+1inmalloc()用于路径分隔符。做到这一点+2,您将有空间用于终止空字符。

于 2011-04-28T18:12:06.127 回答
1

当您分配“路径”字符串时,您忘记添加您在 MAILBOXES 和用户名之间添加的“/”字符的长度。

于 2011-04-28T18:12:53.287 回答
1

看来您需要 malloc 另一个字节以实现零终止。

于 2011-04-28T18:12:58.020 回答
1

您需要为空字符“\x00”分配一个额外的字节作为 C 字符串中的字符串终止符。

目前,您只为 / 字符分配了一个额外的字节。

所以尝试 +2 而不是 +1

于 2011-04-28T18:13:15.427 回答
1

您没有在 char 中为终止 null 进行预算。您的 malloc 长度应该是 +2,而不是 +1。

于 2011-04-28T18:13:23.763 回答
1

+1到底malloc()占了多少/。但是您需要在末尾添加空字符的空间,该字符由strcat(). 所以它是一个+2.

char *path = (char*)malloc(sizeof(char) * (strlen(MAILBOXES) + strlen(username) + 2));
于 2011-04-28T18:13:58.843 回答