我试图实现一个简单的函数,可以连接传递给它的任意数量的字符串。我对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;
}
答案 0 :(得分:2)
您的代码有未定义的行为。标准要求传递给realloc
的指针应该与使用内存管理功能分配动态内存的指针完全匹配。标准规定的内存管理功能有:
aligned_alloc
,calloc
,malloc
和realloc
。
您传递给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
只能与之前由malloc
或realloc
返回的指针一起使用。其他类型的用途(和你一样)会产生不确定的行为。
答案 3 :(得分:0)
mstrcat函数以s指向第一个参数开始。然后你试图realloc()这个指针是一个静态字符串。这不行。您只能重新分配以前由malloc()分配的指针。
我建议您将char *s=first
更改为char *s=strdup(first)
以分配第一个参数的副本,然后此代码应该有效。
串联算法效率很低,但这是另一个故事...(提示:你可能想要枚举参数并跟踪总大小,然后alloc()一个相应的缓冲区然后将所有参数连接到它中)