简体   繁体   English

如何在C中将指针与结构一起使用

[英]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. 我是一名刚接触c的高中生(我之前使用过Java),并且对指针和结构有些困惑,尤其是在将它们作为函数之间的参数传递时。 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. 您的函数makeNewSite()导致分段错误。

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. 变量returnSite是局部变量,在堆栈上创建。 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. 在此代码中,对malloc()的调用将在堆中而不是在堆栈中创建该结构,并且在函数调用之后它不会被破坏。

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 . newSite->date(*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. 我认为发生运行时错误是因为尚未为siteName和Date分配内存。 so when you assign a string to them, you got a runtime error. 因此,当给它们分配一个字符串时,会出现运行时错误。 you can allocate memory for them by malloc as: 您可以通过malloc为它们分配内存,如下所示:

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. 您的版本中的函数makeNewSite()创建一个对象SAVED_SITE returnSite ,并返回其地址,该地址在销毁该对象时将无效。 So I suggest that you should allocate pointer that will be alive forever, if it is not free or delete . 因此,我建议您分配一个永久存在的指针,如果它不是freedelete
  • 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 char* siteName应该更改为固定大小的数组(或者如果需要,可以在运行时分配它),以便它有足够的空间来存储来自scanf数据
  • I modified printSite() to demonstrate how to pass pointer in function. 我修改了printSite()以演示如何在函数中传递指针。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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