我现在正在学习动态内存分配,这很难理解,尤其是当讲师提到DMA和使用指针的结构时。
首先,在我的代码中的第1行,我对“& ptr-> eno”的含义感到困惑。我们启动ptr作为指针,这意味着ptr保持我们保留的内存的地址,让ptr保持地址2046,是“& ptr-> eno”意味着将值写入它指向的2046的地址?
第二,在第2行,如何打印出值,导致“ptr-> eno”包含值“2046”比我打印出来时,它会给我2046号,而不是值i尝试存储在内存位置2046.
我的代码是从讲义中复制过来的,我试图在Visual Studio上运行它,在输入值后它崩溃了。我对C这么新,我的假设可能看起来很愚蠢和痛苦。如果你无法理解我的解释,请告诉我如何使用指针与结构,可能是我可以弄清楚我的错误。谢谢
#include<stdio.h>
#include<stdlib.h>
struct emp
{
int eno;
char ename[20];
float esal;
};
void main()
{
struct emp* ptr;
ptr = (struct emp*)malloc(sizeof(struct emp));
if (ptr=NULL)
{
printf("out of memory error");
}
else
{
printf("enter the value of employee: \n");
scanf_s("%d%s%f", &ptr->eno, ptr->ename, &ptr->esal); // line 1
}
printf("the name is: %s \t the number: %d \t the salary: %f", ptr->ename, ptr->eno, ptr->esal); //line2
}
答案 0 :(得分:4)
此:
if (ptr=NULL)
没有做你想做的事。您需要比较运算符==
,而不是赋值运算符=
。这将始终将ptr
设置为NULL,使得其余代码具有未定义的行为(这通常会导致实际崩溃)。启用和查看编译器警告是避免此问题的一种非常好的方法。
对于实际问题,&ptr->eno
表示&{34; eno
&#34;指向的结构中字段ptr
的地址。在实践中,它将评估ptr
的值,加上从结构开始到字段eno
的偏移量,在这种情况下将为0,因为eno
是第一个字段
此外,printf()
当然应位于else
内,因为只有在ptr
不为NULL时才能运行{。}}。
而且,重要的是:您必须为字符串scanf_s()
提供缓冲区大小。):
与
scanf
和wscanf
不同,scanf_s
和wscanf_s
要求为c
类型的所有输入参数指定缓冲区大小,{{1} },C
,s
或S
中包含的字符串控件集。字符的缓冲区大小作为附加参数传递,紧跟在指向缓冲区或变量的指针之后。
所以,它应该是:
[]
你应该检查它的返回值,否则如果由于某种原因输入失败,你就有可能使用非初始化变量。
请注意,缓冲区的大小似乎指定为const int num = scanf_s("%d%s%f", &ptr->eno, ptr->ename, (unsigned int) sizeof ptr->ename, &ptr->esal);
if (num == 3) // All conversions succeeded, we can rely on them
{
printf("the name is: %s \t the number: %d \t the salary: %f", ptr->ename, ptr->eno, ptr->esal); //line2
}
,而不是unsigned int
,这在我的观点中不是最佳的,因此需要强制转换。
顺便说一下,&#34; DMA&#34;通常意味着&#34; direct memory access&#34;与此无关;那让我困惑了一段时间。
答案 1 :(得分:4)
假设
if (ptr=NULL)
是一个拼写错误(因为随后的&#34;它在我输入值后出现崩溃&#34;不可能发生),这里有一个错误:
scanf_s("%d%s%f", &ptr->eno, ptr->ename, &ptr->esal);
缺少%s
scanf_s("%d%s%f", &ptr->eno, ptr->ename, 20, &ptr->esal);
或者代替硬编码,也许
scanf_s("%d%s%f", &ptr->eno, ptr->ename, (unsigned)sizeof ptr->ename, &ptr->esal);
答案 2 :(得分:1)
投射malloc
的输出(检查[ this ])不是一个好习惯,最简单的方法是
struct emp *ptr;
ptr = malloc(1 * sizeof *ptr);
然后,==
用于等于逻辑比较,所以
if (NULL == ptr)
/* = changed to ==, also put the value first which will help you easily
* fix accidental omission of the second =
*/
{
printf("out of memory error");
exit(1); // Exiting with a non-zero status
}
注意这应作为 [ this ]回答的补充