realloc()失败

时间:2012-02-01 08:44:33

标签: c memory-management

我试图实现一个简单的函数,可以连接传递给它的任意数量的字符串。我对realloc的调用失败了。这是否与我传递给函数的字符串参数存储在数据段中的事实有关,其中realloc看起来是从堆中分配内存?这只是我的一个想法。我是初学者,请原谅,如果它看起来很愚蠢。如何让这个功能运行?

 //Program to implement a function that can concatenate any number of argumnets 

#include<stdio.h>
#include<stdarg.h>
#include<string.h>
#include<stdlib.h>

char *mstrcat(char *first, ...);
int main(int argc, int **argv){
    char *s;
    s=mstrcat("I ","Love ","Stack","Overflow");
    printf("%s\n",s);
}
char *mstrcat(char *first, ...){
       char *s=first,*p;
       int len=0;  // stores the length of the string as it grows
       len=strlen(s);
       va_list aptr; // creates a pointer to the unnamed argument list
       va_start(aptr,first); // initialise aptr to the first unnamed argument
       if(aptr==NULL){
        return s;
      }
      while((p=va_arg(aptr,char *))!=NULL){ // till there are no more arguments to process
         len+=strlen(p);
         if((s=(char *)realloc(s,len+1))!=NULL){
            strcat(s,p);
         }
         else{
            printf("Failed to concatenate\n");    
            return first; 
         }
      }
      return s;
}

4 个答案:

答案 0 :(得分:2)

您的代码有未定义的行为。标准要求传递给realloc的指针应该与使用内存管理功能分配动态内存的指针完全匹配。标准规定的内存管理功能有:
aligned_alloccallocmallocrealloc

您传递给realloc()的指针未被其中任何一个返回,因此未返回未定义的行为。

参考:
c99标准:7.22.3.5 realloc功能

故事梗概:#1

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

#3

  

如果ptr是空指针,则realloc函数的行为类似于malloc函数   指定大小。否则,如果ptr与先前由内存返回的指针不匹配   管理功能,或者如果通过调用free或者释放空间   realloc函数,行为未定义。如果新对象的内存不能   已分配,旧对象未被释放,其值不变。

答案 1 :(得分:0)

关于realloc的一点,size参数是已分配数据的新大小,对于您而言应该是s的旧长度加上{{p的长度1}}(当然,终结者为+1)。

正如您所怀疑的那样,您不能使用first字符串作为重新分配的基础。而是在函数开头将s设置为NULL

答案 2 :(得分:0)

您正在将字符串文字传递给mstrcat函数,它们可能存储在进程的只读区域中,这意味着它们无法修改或调整大小。

realloc只能与之前由mallocrealloc返回的指针一起使用。其他类型的用途(和你一样)会产生不确定的行为。

答案 3 :(得分:0)

mstrcat函数以s指向第一个参数开始。然后你试图realloc()这个指针是一个静态字符串。这不行。您只能重新分配以前由malloc()分配的指针。

我建议您将char *s=first更改为char *s=strdup(first)以分配第一个参数的副本,然后此代码应该有效。

串联算法效率很低,但这是另一个故事...(提示:你可能想要枚举参数并跟踪总大小,然后alloc()一个相应的缓冲区然后将所有参数连接到它中)