如何在不使用realloc()的情况下扩展字符串容量?
我试图找到一种不用如何在不使用realloc()的情况下扩展字符串容量?,c,string,memory-management,malloc,realloc,C,String,Memory Management,Malloc,Realloc,我试图找到一种不用realloc扩展字符串容量的方法。例如,此代码之间的主要区别是什么: void insert(char *dest, char *src, int pos){ char *temp = malloc(strlen(dest)+strlen(src)+1); /* malloc failure handling */ strcpy(temp,dest); //rest of code } 以及: 还是有更好的方法 请注意
realloc
扩展字符串容量的方法。例如,此代码之间的主要区别是什么:
void insert(char *dest, char *src, int pos){
char *temp = malloc(strlen(dest)+strlen(src)+1);
/*
malloc failure handling
*/
strcpy(temp,dest);
//rest of code
}
以及:
还是有更好的方法
请注意,src
和dest
都是使用malloc
Doingmalloc-->memcpy-->free
初始化的,实际上realloc
在概念上就是这样做的,只是稍微优化了一些
由于这种优化,这个问题
这段代码之间的主要区别是什么
可以这样回答,前者在内存碎片方面更快、更有效
如何在不使用realloc()的情况下扩展字符串容量 如果VLA*可用(在C99之前没有,可能在C11中也没有,在C++中也没有),并且您知道输入的最大大小,此大小永远不会导致堆栈溢出,那么您可以执行以下操作:
总而言之,如果开始玩
malloc()
没有理由不去找它的表亲realloc()
realloc
相当于
void *my_realloc(void *old_p, size_t new_size) {
void *new_p = malloc(new_size);
if (!new_p)
return NULL;
size_t old_size = ...;
if (old_size < new_size)
memcpy(new_p, old_p, old_size);
else
memcpy(new_p, old_p, new_size);
free(old_p);
return new_p;
}
void*my\u realloc(void*old\u p,size\u t new\u size){
void*new_p=malloc(新_尺寸);
如果(!新建)
返回NULL;
尺寸旧尺寸=。。。;
if(旧尺寸<新尺寸)
memcpy(新尺寸、旧尺寸、旧尺寸);
其他的
memcpy(新尺寸、旧尺寸、新尺寸);
免费(旧版);
返回新的\u p;
}
除了realloc
可以扩展或收缩现有内存块之外。这样可以避免将字节从旧位置复制到新位置
这意味着
realloc
至少与malloc
+memcpy
+free
一样快,但可能更快。主要区别在于,一个好的realloc实现可以进行优化,如果可能,可以跳过拷贝。(这可能类似于检查内存中是否有连续的可用空间来扩大分配,但这取决于内存的管理方式)
如果您不想在运行时编写某种内存管理来处理长度未定义的字符串,那么没有比realloc更好的解决方案了。可能是一个链表。可能无法使用
string.h
操作。这两个代码的作用大致相同,但它们都有缺陷,调用insert
的人将永远看不到新指针。在C语言中,变量是通过值传递的。实际上,realloc
基本上是这样做的:1。分配新的大小。2.将旧缓冲区的内容复制到新分配的内存。3.释放旧的缓冲区。realloc有什么问题?我们需要更多的上下文信息。基本上,如果不使用某种形式的动态内存分配,就无法完成此操作。“主要区别”是第二个代码片段不必要地强制转换分配函数的结果,该函数返回void*
!;)。。。而realloc
也可能会缩小现有的内存块。@Jabberwocky,的确如此。谢谢。我还假设strcpy()在字符串管理方面优于memcpy(),这就是为什么我首先避免使用realloc的原因。VLA方法是一个非常糟糕的主意,我撤回了基于它的初始向上投票。如前所述,它可以处理硬编码的字符串,但如果其中任何一个字符串都是不受控制的输入,那么它就是等待发生的堆栈溢出/可解释堆栈冲突错误。正确使用VLA是非常微妙的,很少适用,并且不属于似乎只是在学习语言的人的答案。@R。。写这篇文章的时候我已经有点不舒服了,但是。。。好。。。只是忽略了它。你说得太对了。需要考虑现在该怎么做,因为它甚至被接受了…@ashs:“假设strcpy()在字符串管理方面比memcpy()好,这就是为什么我避免使用realloc err什么?你避免了realloc()
确切原因是什么?@alk主要是为了避免realloc
失败,但我的问题是只复制dest
中的第一个i
字符,所以我计划改用strncpy()
。很抱歉没有说清楚。
#include <stdio.h>
#include <string.h>
...
char s1[] = "123";
char s2[] = "456";
char s3[] = "789";
char s[strlen(s1) + strlen(s2) + strlen(s3) + 1];
strcpy(s, s1);
strcat(s, s2);
strcat(s, s3);
puts(s);
123456789
void *my_realloc(void *old_p, size_t new_size) {
void *new_p = malloc(new_size);
if (!new_p)
return NULL;
size_t old_size = ...;
if (old_size < new_size)
memcpy(new_p, old_p, old_size);
else
memcpy(new_p, old_p, new_size);
free(old_p);
return new_p;
}