【问题标题】:C alocate memory using malloc [duplicate]C使用malloc分配内存[重复]
【发布时间】:2020-11-01 18:24:19
【问题描述】:
我不太明白。
char *string;
string = malloc(1);
if (string == NULL) {
printf("Couldn't able to allocate requested memory\n")
} else {
string = "testing";
}
printf("Dynamically allocated memory content : %s\n\n\n", string );
string "testing" 有 7 个字符 + null 作为字符串的结尾。
如果我用 malloc(1) 分配内存,我会保留 1 个字节的内存,我会分别为 1 个字符保留内存,因为 1 个字符有 1 个字节的内存。但是当我打印这个字符串时,结果是“testing”,但我想应该打印“t”,因为为 1 个字符保留 1 个字节的内存。
【问题讨论】:
标签:
c
string
pointers
memory-management
【解决方案1】:
就像其他答案指出的那样,您将字符串文字的 address 分配给 string - 您没有将字符串文字的 contents 复制到内存string指向。
问题是你不能使用= 运算符来分配字符串,因为字符串(包括像"testing" 这样的字符串字面量)被存储为字符类型的数组,而数组表达式“decay ” 在大多数情况下指向指针表达式。
要将字符串contents从一个数组复制到另一个数组,您需要使用strcpy、strncpy或memcpy等库函数:
strcpy( string, "testing" );
在这种情况下,由于string 指向的缓冲区不够大,无法存储文字内容,因此您会遇到未定义的行为 - 您可能会遇到运行时错误,您可能不会。你可能会覆盖一些重要的东西,你可能不会。编译器和运行时环境都不需要发出任何类型的警告。
不幸的是,程序员需要确保您的目标缓冲区足够大以存储字符串或截断字符串以使其适合目标缓冲区。
【解决方案2】:
int x = 0;
x = 42;
最终结果完全一样
int x = 42;
无需先通过0。
指针并不神奇。
char* string = malloc(...);
string = "testing";
最终结果与1完全相同
char* string = "testing";
无需先通过malloc。
字符串不是指针。字符串是 以空字符结尾的字符数组。为了分配一个字符串,你:
- 分配一个合适长度的字符数组。
-
复制一个以null结尾的字符序列到所述数组(这与复制指针完全不同)。
所以
// 1 Allocate an array of characters of suitable length
char *string = malloc(strlen("testing")+1);
// note suitable length
// the variable `string` points to the first character of the array just allocated
// 2 Copy a null-terminating sequence of characters to said array
strcpy (string, "testing");
// other ways of copying strings exist
为简洁起见,省略了检查malloc 的返回值。
1 有一些区别:malloc 分配内存,第一个片段愉快地丢弃,导致内存泄漏。但是,您的程序无法检测到这种差异,这意味着可观察到的程序行为完全相同。您只能从程序外部检测差异,例如通过调试器跟踪它。
【解决方案3】:
当你处理指针时,你需要换个角度思考。
以下语句使string 指向堆中某个1字节长的内存位置。
string = malloc(1);
当你指定string 指向一个文字时,你让string 指向内存中的另一个位置。
string = "testing"
string 指向的先前字节已泄露,即它不再具有引用。
+---+
string -> | |
+---+
+---+
string | |
\ +---+
\ +-----------+
--> | testing\0 |
+-----------+
【解决方案4】:
您不会将字符串"testing" 的内容全部或部分写入malloc() 分配的动态内存中:
string = "testing";
相反,您覆盖指针 string 以指向用字符串 "testing" 填充的只读内存。
请注意,像"testing" 这样的字符串文字会获得指向只读位置的指针。
当您尝试打印内容时,string 指向的位置:
printf("Dynamically allocated memory content : %s\n\n\n", string );
它打印在这个只读内存中分配的字符串"testing",而不是存储在分配的动态内存中的字符串。
不必要分配的1字节浪费是memory leak。
【解决方案5】:
您正在泄漏您分配的一个字节。
让我们用地址来做:(更清晰的小地址)
假设 malloc 返回一个指向地址 0x4000 的指针。您将其存储在字符串中。现在字符串是一个指向 0x4000 的指针。
例如,“测试”的地址为 0x1200。字符串现在指向 0x1200。
你给 printf a 地址 0x1200 并且有字符串“testing” ==> testing 被写入控制台。