繁体   English   中英

为函数内部的结构分配指针

[英]Allocate memory for a pointer to a struct inside a function

我正在尝试编写一个单独的程序,该程序调用一个函数来为一定数量的“学生”结构动态分配内存。

我的主程序太大而无法处理,因此我创建了一个较小的程序来帮助我更轻松地弄清楚自己在做什么:

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

void structMemInit(myName **);

int main(void){

    myName *myNameIs;

    structMemInit(&myNameIs);

    printf("%s\n", myNameIs[1].name);

    return 0;
}

void structMemInit(myName **myNameIs){
    *myNameIs = (myName *) calloc(5, sizeof(myName));
    if(myNameIs == NULL){
        printf("allocating memory didn't work!\n");
        exit(1);
    }
    else if(myNameIs != NULL)
        (*myNameIs)[1].name = "Zach";
}

memtest.h文件为:

typedef struct{
    char *name;
}myName;

上面所有程序试图做的就是将指向结构的指针传递到函数“ structMemInit”中,并为该结构分配干净的空间。 然后要查看它是否有效,我将变量char设置为一个名称。 在发生所有这些情况之后,您将离开函数并返回至main。 然后,我在结构中打印该名称以显示其有效。

运行时,程序始终给出段错误。

如果您想知道为什么我有一个单独的.h文件,我的实际程序要大得多,并且有几个全局声明的结构,我的老师要求我为这些结构保留一个单独的.h。

谢谢! 扎克

如果您坚持要传递指针,则应该通过引用进行传递,因此它是指向指针的指针,因为itslef函数将修改指针中的地址。

如果您的函数返回一个指针,您会更好。

//function for allocating the memory
myName *structMemInit(void)
{
    myName *myNameIs = (myName *)calloc(1, sizeof(myName));
    if (myNameIs == NULL) {
        printf("allocating memory didn't work!\n");
        exit(1);
    } else {                     // don't repeat the negation of the condition
        myNameIs->name = "Zach"; // No need for \0, it's automatic
        return myNameIs;
    }
}

//Usage
myName *myNameIs = structMemInit();

顺便说一句,它是int main(void)而不是int main()

在回答之前,我应该说我不太精通C语言,因为我是C ++程序员,所以接下来可能会有一些语法错误。 希望我的观点足以使任何错误都非常重要。

出现段错误的原因是因为您对将指针作为函数的参数传递时发生的误解。

想象一下,例如,您的程序如下:

int main(void){
    int i;

    setInteger(i);

    printf("%d\n", i);

    return 0;
}

void setInteger(int n){
    n = 12;
}

在这种情况下,您可以清楚地看到输出将是未定义的,因为变量i尚未初始化,并且已按值传递给setInteger 函数返回时,对n任何更改都不会传递回i

如果程序被替换为

int main(void){
    int i;

    setInteger(&i);

    printf("%d\n", i);

    return 0;
}

void setInteger(int *n){
    *n = 12;
}

那么,由i输出的值将为12

程序中发生了同样的事情,您正在通过value传递指针。

如果要通过引用传递,则需要执行以下操作:

int main(void){

    myName *myNameIs;

    structMemInit(&myNameIs); // pass the address of your pointer

    printf("%s\n", myNameIs->name);

    return 0;
}

//function for allocating the memory
void structMemInit(myName **myNameIs){ // argument is pointer-to-pointer 
    *myNameIs = (myName *) calloc(1, sizeof(myName)); // dereference pointer to get underlying pointer
    if(*myNameIs == NULL){
        printf("allocating memory didn't work!\n");
        exit(1);
    }
    else{
        *myNameIs->name = "Zach";
    }

}

不幸的是,那还不是问题的结局。 尽管您已经为myName对象分配了内存,但是尚未为字符数组分配内存。

要返回字符串“ Zach”,您需要执行以下操作:

*myNameIs->name = (char*)malloc(5*sizeof(char)); // need extra char for \0
strcpy(*myNameIs->name, "Zach");

请注意:

typedef struct{
    char name[20];
} myName;

不同于:

typedef struct{
    char *name;
} myName;

在第二种形式中,您没有为字符串分配任何空间。 您只是在为指针分配空间。

下面是程序的运行版本。 如果要使用strcpy(p->name, "Zach"); 您需要使用char name[20]; 在你的结构中。

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

typedef struct{
    // char name[20];
    char *name;
} myName;

myName *structMemInit();

int main(){
    myName *myNameIs;
    myNameIs = structMemInit();
    if (myNameIs)
        printf("%s\n", myNameIs->name);
    return 0;
}

//function for allocating the memory
myName *structMemInit(){
    myName * p = (myName *) malloc(sizeof(myName));
    if (p == NULL){
        fprintf(stderr, "allocating memory didn't work!\n");
    } else {
        fprintf(stderr, "allocating %d memory work!\n", sizeof(myName));
        // strcpy(p->name, "Zach");
        p->name = strdup("Zach");
    }
    return p;
}

暂无
暂无

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

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