简体   繁体   中英

How do I Use Pointers With Structs in C

Hey I'm new to stack overflow, so please give constructive criticisms about my post!

I am a highschool student new to c (I have used java a bit before), and I am a little confused about pointers and structures, especially when passing them as parameters between functions. I wrote the following code, which compiles but then has a segmentation fault at runtime (I think this means that memory overlapped its allocated space, correct me if I'm wrong). If anyone could explain why and where this is happening, that would be great!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct savedSite{
    char *siteName; 
    char *date; 
    int x;
} SAVED_SITE;

void printSite(struct savedSite site){
    printf("Site: %s\nDate Added: %s\nID:            
    % d\n",site.siteName,site.date,site.x);
}

SAVED_SITE* makeNewSite(){
    SAVED_SITE returnSite;
    printf("Enter Site Name");
    scanf("%s", returnSite.siteName);
    return &returnSite; 
}

int main() 
{   
    SAVED_SITE newSite;
    newSite = *makeNewSite();
    newSite.date = "3/13/2017";
    newSite.x = 89; 
    return 2;
}

Thanks!

Edit: I am overwhelmed with how quickly I received answers here! Thank you guys so much, it's incredible!

Your function makeNewSite() is causing the segmentation fault.

SAVED_SITE* makeNewSite(){
    SAVED_SITE returnSite;
    printf("Enter Site Name");
    scanf("%s", returnSite.siteName);
    return &returnSite; 
}

The variable returnSite is a local variable and is created on the stack. As soon as the function call ends, that variable is destroyed. However, you're returning its address and trying to access it which is causing the segmentation fault.

You can try this, instead:

SAVED_SITE* makeNewSite(){
    SAVED_SITE* returnSite = malloc(sizeof(SAVED_SITE));
    printf("Enter Site Name");
    scanf("%s", returnSite->siteName); // Not sure about this allocation
    return returnSite; 
}


int main() {   
    SAVED_SITE* newSite = makeNewSite(); // Get the pointer here.
    newSite->date = "3/13/2017";
    newSite->x = 89;
    free (newSite); 
    return 2;
}

In this code, the call to malloc() will create the struct in the heap instead of that stack and it won't be destroyed after the function call.

Also note that I am using -> instead of . in the main function. This is because I have a pointer to the struct and not the struct itself. newSite->date is the same as doing (*newSite).date .

 #include<stdio.h>
 #include<string.h>
 #include<stdlib.h>
typedef struct savedSite{
char *siteName;
char *date;
int x;
} SAVED_SITE;
SAVED_SITE returnSite;
void printSite( SAVED_SITE* site){
printf("Site: %s\nDate Added: %s\nID:% d\n",site->siteName,site-   >date,site->x);
}

SAVED_SITE* makeNewSite(){
SAVED_SITE* returnSite = malloc(sizeof(SAVED_SITE));
printf("Enter Site Name");
scanf("%s", returnSite->siteName);
return returnSite;
}


int main() {
SAVED_SITE* newSite = makeNewSite(); // Get the pointer here.
newSite->date = "3/13/2017";
newSite->x = 89;
return 2;
}

I think the runtime error occurred since you haven't allocated memory for siteName and Date. so when you assign a string to them, you got a runtime error. you can allocate memory for them by malloc as:

sitename = (char *)malloc(20 * sizeof(char));

or simply get this memory in your struct:

char sitename[20];

you shouldn't allocate memory for your whole structure. only for these variables I mentioned. don't forget to free the memory you allocated.

Here is some change you should do.

  • The function makeNewSite() in your version create a object SAVED_SITE returnSite , and return its address, which will be invalid when the object is destroyed. So I suggest that you should allocate pointer that will be alive forever, if it is not free or delete .
  • char* siteName should be changed to a fix size array(or you can allocate it at run time if you want) so it can have enough room for storing data from scanf
  • I modified printSite() to demonstrate how to pass pointer in function.

Here is example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct savedSite{
    char siteName[128]; // 
    char *date; 
    int x;
} SAVED_SITE;

void printSite(struct savedSite *site){       // accept pointer as an argument
    printf("Site: %s\nDate Added: %s\nID:            
    % d\n",site->siteName,site->date,site->x);
}
SAVED_SITE* makeNewSite(){
    SAVED_SITE *returnSite = new SAVED_SITE; // allocate a struct that will live forever if not be deleted
    printf("Enter Site Name");
    scanf("%s", returnSite->siteName);
    return returnSite; // the pointer returned here is valid until you delete it
}
int main() 
{   
    SAVED_SITE *newSite; // create a pointer which doesn't point to anything
    newSite = makeNewSite(); // now the newSite* points to data struct
    newSite->date = "3/13/2017";
    newSite->x = 89; 
    //remember to delete the allocated memory when you don't need it anymore
    delete newSite;
    return 2;
}

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