如何在C中使用带有结构的指针

时间:2017-03-16 06:00:11

标签: c

嘿,我是堆叠溢出的新手,所以请对我的帖子给予建设性的批评!

我是c的新学生(之前我曾经使用过java),我对指针和结构有点困惑,特别是在将它们作为函数之间的参数传递时。我写了下面的代码,它编译但在运行时有一个分段错误(我认为这意味着内存重叠了它的分配空间,如果我错了就纠正我)。如果有人能解释为什么以及在哪里发生这种情况,那就太棒了!

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

谢谢!

编辑: 我很快就收到了答案!非常感谢你们,这太不可思议了!

4 个答案:

答案 0 :(得分:1)

你的函数makeNewSite()导致了分段错误。

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

变量returnSite是一个局部变量,在堆栈上创建。一旦函数调用结束,该变量就会被销毁。但是,您将返回其地址并尝试访问它,这会导致分段错误。

你可以试试这个:

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

在这段代码中,对malloc()的调用将在堆中创建结构而不是该堆栈,并且在函数调用之后它不会被销毁。

另请注意,我在main函数中使用->而不是.。这是因为我有一个指向结构的指针而不是结构本身。 newSite->date与执行(*newSite).date相同。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我认为发生了运行时错误,因为您还没有为siteName和Date分配内存。因此,当您为它们分配字符串时,您会遇到运行时错误。你可以通过malloc为它们分配内存:

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

或者只是在结构中获取此内存:

char sitename[20];

你不应该为整个结构分配内存。仅针对我提到的这些变量。 不要忘记释放你分配的记忆。

答案 3 :(得分:-1)

这是你应该做的一些改变。

  • 您的版本中的函数makeNewSite()创建一个对象SAVED_SITE returnSite,并返回其地址,该对象在销毁对象时无效。所以我建议你应该分配永远存活的指针,如果它不是freedelete
  • char* siteName应更改为修复大小数组(或者您可以在运行时根据需要进行分配),以便它有足够的空间存储来自scanf的数据
  • 我修改了printSite()以演示如何在函数中传递指针。

以下是示例:

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