我想在一个已存在的字符串中分配内存,并且仍然想保存该字符串中存储的数据
#include <stdio.h>
#include <string.h>
main()
{
char *str1= "hello";
char *str2= "Abhimanyu";
char *str = malloc( strlen(str1) + strlen(str2) +1 );
strcpy(str,str1);
strcat(str,str2);
printf("%s",str);
return 0;
}
我想要的是,我分配一些使用malloc在现有的str1
和不使用str
是可能的吗?
我看到的唯一方法是以下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HELLO "hello"
int main( void )
{
char *str2 = "Abhimanyu";
char *str1 = malloc( sizeof( HELLO ) );
strcpy( str1, HELLO );
str1 = realloc( str1, strlen( str1 ) + strlen( str2 ) +1 );
strcat( str1, str2 );
printf( "%sn", str1 );
free( str1 );
return 0;
}
我想要的是,我分配一些使用malloc在现有的str1和不使用STR是可能的吗?
你当然可以把str1
指向其他内存,如果你不再需要它指向字符串字面量。
只需赋新值。
重分配功能为realloc
。
你可能需要的一些事实:
- 字符串字面值不能更改,即使它的类型是
char[]
,它实际上是常量。
它是静态分配的,因此与malloc
等无关。
所有常量字面值,包括字符串字面值,都可能共享存储空间。有一个POSIX函数用于复制字符串(内存内部分配与malloc
):strdup()
- 您可以在堆上使用兼容函数分配
realloc
内存。包括:malloc
calloc
realloc
(strdup
)。别忘了free
. - 如果你重新分配内存,除非重新分配失败(返回
NULL
),你可能不再使用旧指针。所有数据都从旧的内存块复制到新的内存块,直到新旧长度的最小值。
旁白:注意main
几乎总是有一个int
的返回类型,隐式返回类型是古老的遗产。
如果您使用一个不错的编译器,要求所有警告-Wall -Wextra -pedantic
并选择一个现代标准(C99或C11)将对您有所帮助。
您可以使用realloc来增加指针指向的内存块,但是realloc的实现可能最终会将您的数据移动到内存中的不同位置并更改指针的地址,因此您应该始终仔细检查您的指针。如果请求的新大小大于可用的大小,则可能发生这种情况。
如果有一个很好的理由,为什么你需要能够动态地调整指针指向的内存块的大小,那么你可能需要考虑建立自己的内存分配器或缓冲池,并在池中管理内存的所有权
我相信你是在问你是否可以接受这个声明:
char * str1 = "hello";
并以某种方式导致str1
指向的一些额外空间。
答案是不要这样做!注意,str1
是一个本地(堆栈)变量。它可能指向某个文字池,但也可能指向堆栈上分配的更多空间。
所以做这样的事情
char * str1 = hello;
...
str1 = realloc (str1, 100);
可能导致dom!(一个适合OP编码风格的UNIX第六版笑话)。
您可以使用realloc
尝试调整先前分配的大小。它不在任意指针上工作,比如你的str1 = "hello"
†-你需要分配初始区域,例如malloc
。它也可能最终在不同的地址分配一个新的区域(并复制旧区域的内容),即,您必须更新所有指向旧区域的指针,以指向realloc
返回的新区域。
如果这些约束是不可接受的,那么你就不走运了,你需要用其他的方式来设计你的程序(例如,设置一个最大长度,并保留那么多的空间来开始,然后根据需要使用多少就使用多少)。
†还要注意,字符串字面值,如"hello"
,是不可修改的。解决这个问题的典型方法是使用数组代替,例如char str1[] = "hello"
,但这也不能调整大小。(但是,如果您知道稍后将在那里存储一个更长的字符串,则可以为其指定比初始内容所需的更大的大小。)