我在学习C语言的malloc和指针时遇到了困难:
到目前为止我学到了什么:
指针是内存地址指针。
malloc()
分配内存位置并返回内存地址。
我正在尝试创建一个程序来测试malloc
和指针,这就是我所拥有的:
#include<stdio.h>
main()
{
char *x;
x = malloc(sizeof(char) * 5);
strcpy(*x, "123456");
printf("%s",*x); //Prints 123456
}
我期待一个错误,因为我提供给malloc
的大小是5,我把6个字符(123456)放到指针指向的内存位置。这里发生了什么?请帮帮我。
更新
在哪里学习malloc和指针?我对星号这个东西感到困惑,就像什么时候使用星号等。在我学习这个东西之前我不会休息!谢谢!
答案 0 :(得分:5)
您正在调用未定义的行为,因为您正在编写(或尝试写入)超出已分配内存的范围。
其他挑剔:
strcpy()
,所以您正在复制7个字节,而不是您在问题中声明的6个字节。strcpy()
的调用存在缺陷 - 您正在传递char
而不是指向char
的指针作为第一个参数。-Wall
。<stdlib.h>
包含malloc()
,为<string.h>
添加strcpy()
。int main()
(或更好,int main(void)
)。return(0);
的末尾看到明确的main()
,即使C99遵循C ++ 98并允许你省略它。你可能不幸并且暂时不使用未定义的行为,但像valgrind这样的工具应该指出你的方式的错误。实际上,malloc()
的许多实现分配了8个字节的倍数(有些是16个字节的倍数),并且鉴于您精心地不跨越8字节分配,您实际上可能会侥幸逃脱它。但是好的调试malloc()
或valgrind
会指出你做错了。
请注意,由于在从free()
返回之前没有main()
分配的空间,因此您(在此上下文中相对无害)会泄漏它。另请注意,如果您复制的字符串较长(比如字母表),特别是如果您尝试free()
分配的内存,或者在第一个字符串结束后再尝试分配其他内存块,然后你更有可能看到你的代码崩溃。
未定义的行为是无条件的。什么事情都可能发生。诊断它不需要任何系统。避免它!
答案 1 :(得分:3)
如果你调用malloc,你可以在堆上获取和寻址内存区域。 如果它返回,例如1000你的记忆会是这样的:
Adr Value
----------
1000 1
1001 2
1002 3
1003 4
1004 5
1005 6
1006 0
调用strcpy()之后。你写了7个字符(比分配的多2个)。
x == 1000(指针地址)
* x == 1(取消引用值x指向)
编译器没有警告或错误消息,因为C没有任何范围检查。
答案 2 :(得分:2)
我的三分钱:
使用x,因为(* x)是存储在x处的值(在您的情况下是未知的) - 您正在写入未知的内存位置。它应该是:
strcpy(x, "123456");
其次 - “123456”不是6个字节,它是7.你忘记了尾随零终结符。
您的程序包含当前代码可能有效,但无法保证。
我会做什么:
#include<stdio.h>
main()
{
char str[] = "123456";
char *x;
x = malloc(sizeof(str));
strcpy(x, str);
printf("%s",x); //Prints 123456
free(x);
}
答案 3 :(得分:1)
首先,您的代码存在一个问题:
x是指向您为5个字符分配空间的内存区域的指针。 * x它是第一个字符的值。 你应该使用strcpy(x,“123456”);
其次,分配5个字节后的内存可以有效,因此您不会收到错误。
答案 4 :(得分:0)
#include<stdio.h>
main()
{
char *x;
x = malloc(sizeof(char) * 5);
strcpy(x, "123456");
printf("%s",x); //Prints 123456
}
使用此...它将起作用
查看您的&amp;和我的计划
现在你在这里分配5个字节&amp;写入6个字节,因此第6个字节将存储在下一个连续的地址中。这个额外的字节可以通过内存管理分配给其他一个字节,所以任何时候额外的字节都可以被其他程序更改,因为第6个字节不是你的,因为你还没有malloc'd ...这就是为什么这是称为未定义的行为。