我注意到,当在分配的malloc()
的数组中编写字符串时,其值会更改。明确的是,这是复制此"错误"的代码:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#define N (20)
int main()
{
char * a_p;
a_p = malloc( N * sizeof(char));
printf(" * 01 pointer -> %pn", a_p);
a_p = "something";
printf(" * 02 pointer -> %pn", a_p);
printf("-- TEST --n");
return 0;
}
执行时,输出为:
* 01 pointer -> 0x1332010
* 02 pointer -> 0x4006b9
-- TEST --
我期望具有相同的价值,因为我没有更改指针点的位置(至少不是直接)。使用free()
时,这会导致问题。木头下发生了什么?我想念什么?如何以正确的方式做这些事情?
您的问题
您正在用malloc()
为指针分配内存,但是您将指针变量分配给其他东西("something"
,具有其自己的地址),而不是填充新分配的指针。
解决方案
您应该使用strdup()
函数,该函数分配内存并在分配的内存中复制字符串:
a_p = strdup("something");
或strcpy()
函数,该功能采用malloc()
'D指针和一个字符串,以在指向内存中复制:
a_p = malloc(N * sizeof(char));
strcpy(a_p, "something");
您直接更改指针。这个语句
a_p = "something";
等于
a_p = &"something"[0];
字符串文字具有字符数组的类型。例如,字符串文字"something"
具有类型char[10]
。
来自C标准(6.4.5字符串文字)
6在翻译阶段7中,将一个字节或值零代码附加到 每个由字符串文字产生的多重字符序列 78)然后,多型字符序列用于 初始化一系列静态存储持续时间和长度 足以包含序列。对于字符串文字, 数组元素具有类型char,并用 多重字符序列的个体字节...
在表达式阵列中使用的,极少数例外被转换为指针转换为其第一个元素。
来自C标准(6.3.2.1 lvalues,阵列和功能指定器)
3,除非是操作员的操作数或Unary&amp; 运算符,或者是用于初始化数组的字符串 具有"类型的数组"类型的表达式转换为 用类型的"键入指针"的表达式指向初始 数组对象的元素,不是lvalue。如果数组对象 有寄存器存储类,行为不确定。
所以在此语句之后
a_p = "something";
指针指向静态存储持续时间的字符串文字的第一个字符。
我认为你是说
strcpy( a_p, "something" );
那就是您想在动态分配的内存中复制字符串字面。
考虑到即使您还可以编写以下代码
char *p1 = "string";
char *p2 = "string";
那么,p1
不必等于p2
,因为根据编译器选项,编译器可以将这两个相同的字符串文字放在不同的内存范围内。
所以if语句
if ( p1 == p2 )
可以产生 true
或 false
。将其分配给a_p
时的第一个元素。该地址正在打印。
并且由于您不保留分配的内存的地址,因此内存泄漏。
您也不能在free
中使用它,这给出了足够的提示,即不会动态分配它。从标准
免费功能导致PTR指向的空间为 被交易,也就是说可以进一步分配。如果
ptr
是 无效指针,没有任何动作。否则,如果参数不 匹配由内存管理功能返回的指针或 如果通过free
或realloc
的呼叫来处理该空间,则 行为不确定。
很好,这说明了为什么在尝试free
内存时遇到问题的原因。
再次具有复制之类的东西,您需要使用strcpy
或strncpy
或strdup
(符合POSIX)。
有关更多信息,请检查此链接。Standard说,它明确地将其视为翻译步骤中的数组。
尤其是此部分 - (衰减指针是char*
类型)
对于字符串文字,数组元素具有类型
char
,并用多键的个体字节初始化 字符序列。
字符串文字"something"
代表一个无效的字符系列,这些字符生存在某个只读区域中(如果您在gnu/linux系统上构建/链接/运行,则很可能.text
)。
最初,a_p
指向malloc
在其中分配缓冲区的内存区域中的某个地方。您可以自由写入a_p
点,free()
IT等的位置。执行分配a_p = "something";
时,您不是在将字符写入a_p
点的位置,而是将该指针更改为指向该字符串的开始。现在,您要指向malloc
并未分配的(仅读取)内存,因此其相应的free
函数无法做任何有意义的事情。
使用strcpy
(或为安全而更好,strncpy
)将字符复制到目的地,a_p
。