2

对于我的生活,我无法弄清楚为什么这个程序不起作用。我正在尝试使用指针连接两个字符串并不断收到此错误:

a.out(28095) malloc: *** error 
for object 0x101d36e9c: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug

我的 str_append.c:

#include <stdio.h>
#include <stdlib.h>
#include "stringlibrary.h"  /* Include the header (not strictly necessary here) */

//appends s to d
void str_append(char *d, char *s){
  int i=0, j=0;

  d = realloc(d, strlength(d)+strlength(s)+1);
  //find the end of d
  while(*(d+i)!='\0'){
    i++;
  }


  //append s to d
  while(*(s+j)!='\0'){
    *(d+i)=*(s+j);
    i++;
    j++;
  }
  *(d+i)='\0';


}

我有自己的 strlength 函数,我 100% 确定它有效。

我的 main.c:

#include <stdio.h>
#include <stdlib.h>
#include "stringlibrary.h"

int main(int argc, char **argv)
{
 char* str = (char*)malloc(1000*sizeof(char));
 str = "Hello";
 char* str2 = (char*)malloc(1000*sizeof(char)); 
str2 = " World";

str_append(str, str2);


 printf("Original String: %d\n", strlength(str));
 printf("Appended String: %d\n", strlength(str));


return 0;
}

我尝试重新分配给临时变量并收到相同的错误。任何帮助表示赞赏。

编辑:感谢所有的答案。这个网站很棒。我不仅知道我哪里出错了(我猜是简单的错误),而且我发现了一个我不知道的关于弦乐的大漏洞。因为我不能使用 strcpy 函数,所以我自己实现了。它基本上是 strcpy 的源代码。

char *string_copy(char *dest, const char *src)
{
 char *result = dest;
 while (*dest++ = *src++);
 return result;
}
4

4 回答 4

5

你的问题在这里

char* str = (char*)malloc(1000*sizeof(char));
str = "Hello";

首先,您为 1000 个字符分配空间并将指针指向该内存的开头。
然后在第二行中,将指针指向导致内存泄漏的字符串文字。
您的指针不再指向分配的内存。
稍后在您的函数中,您尝试更改只读的字符串文字。

于 2013-04-03T02:49:40.193 回答
4

您正在尝试重新分配指向静态变量的指针。当你设置

str = "Hello";

您正在静态分配该变量(即它将在​​编译时分配)。那么它就不是用于其他目的的有效指针,包括realloc. malloc通过丢弃指向该内存的唯一指针,您还浪费了您在上面一行中检索到的所有空间。

您需要做的是使用strcpy分配值:

strcpy(str, "Hello");

然后你仍然有一个动态分配的指针,你可以将它用于realloc.

于 2013-04-03T02:50:13.977 回答
2
char* str = (char*)malloc(1000*sizeof(char));
str = "Hello";

应该:

char* str = malloc (1000);
strcpy (str, "Hello");

前者分配一些内存并将该内存的地址存储到str指针中,然后将指针更改str指向不同的(未分配的)内存。

这就是你看到的原因pointer being realloc'd was not allocated

后一个代码段str指向分配的内存,只是将字符串复制到该内存中。


而且,顺便说一句,您永远不应该从mallocC 中转换返回值——它可以隐藏某些细微的错误,而且这是不必要的,因为 C 完全能够将void*返回的值隐式转换为任何其他指针类型。

此外,由于sizeof(char)始终是一,因此您永远不需要乘以它。它通常会不必要地使代码混乱。

最后,虽然在这种情况下可能不太重要,但 C 标准保留了以和开头str的标识符(每个后跟一个小写字母)以供将来的库方向使用,因此您可能需要重新考虑您对事物的使用,例如如果您想要未来的可移植性。memwcsstrlength()

于 2013-04-03T02:51:30.360 回答
1

字符串文字(例如 : "MAMA" "MEME")是不可变的。但是,如果您使用字符指针(例如char * s = (char*)malloc(sizeof(char) * LEN)并分配它们,则无法重新分配它们,那么它们是可变的。

这里 :

char* str = (char*)malloc(1000*sizeof(char));
str = "Hello"; //no error BUT wasted memory and cant be reallocated anymore (literal)

您应该在字符串操作中使用内置函数...

于 2013-04-03T03:16:45.807 回答