简体   繁体   中英

Dynamic Memory Allocate, how to use pointer correctly when dealing with Structure?

I am learning about Dynamic Memory Allocate now and it's hard to understand, especially when the lecturer mentioned about DMA and structure using pointer.

First, at the line 1 in my code, i get confused what "&ptr->eno" means. we initiate ptr as a pointer so it means ptr hold the address of the memory we reserved, lets say ptr hold the address 2046, is that "&ptr->eno" means writing value to the address of 2046 it point to?

Second, at the line 2, how i can print out the value, cause "ptr->eno" contains value "2046" than when i print it out, it gonna give me the number 2046, not the value i try to stored in the memory location 2046.

My code was copied from the lecture note, i tried to run it on Visual studio, it crashed after i input the values. I am so new with C, my assumption may looks stupid and painful to understand. if you can't understand my explanation, please tell me how to use pointer with structure, may be i can figure out my mistake. Thank you

#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
}

This:

if (ptr=NULL)

doesn't do what you want. You want the comparison operator == , not the assignment operator = . This will always set ptr to NULL, making the rest of the code have undefined behavior (which often leads to crashes in practice). Enabling, and looking at , compiler warnings is a very good way of avoiding this problem.

For the actual question, &ptr->eno means "the address of the field eno in the struct pointed to by ptr ". In practice it will evaluate to the value of ptr , plus the offset from the start of the structure to the field eno , which in this case will be 0 since eno is the first field.

Furthermore, the printf() should of course be inside the else , since you can only run that if ptr is not NULL.

And, importantly: you must provide a buffer size for the string to scanf_s() .):

Unlike scanf and wscanf , scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c , C , s , S , or string control sets that are enclosed in [] . The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable.

So, it should be:

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
}

And you should check its return value, otherwise you risk using non-initialized variables if the input fails for some reason.

Note that the size of the buffer seems to be specified as unsigned int , and not size_t , which is ... not optimal in my point of view so the cast is needed.

By the way, "DMA" typically means " direct memory access " and has nothing to do with this; that was confusing me for a while.

Assuming that

if (ptr=NULL)

was a typo (since the subsequent "it crashed after i input the values" could not have happened), there is a fault here:

scanf_s("%d%s%f", &ptr->eno, ptr->ename, &ptr->esal);

is missing the required size argument for %s

scanf_s("%d%s%f", &ptr->eno, ptr->ename, 20, &ptr->esal);

or instead of hard coding, perhaps

scanf_s("%d%s%f", &ptr->eno, ptr->ename, (unsigned)sizeof ptr->ename, &ptr->esal);

It is not a good practice to cast the output of malloc (check [ this ] ), the simplest way to do it would be

struct emp *ptr;
ptr = malloc(1 * sizeof *ptr);

Then, == is used for equal to logical comparison, so

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
} 

Note This should be taken as a supplement to [ this ] answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM