如何在不使用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
Doing
malloc-->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;
}