首页 文章

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

提问于
浏览
0

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

我的主程序太大而不能搞乱所以我创建了一个较小的程序来帮助我更容易地弄清楚我在做什么:

#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文件 .

谢谢!扎克

3 回答

  • 1

    如果你坚持传递指针,它应该是引用,所以它是指针的指针,因为函数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() .

  • -1

    在我回答之前,我应该说我不是很精通C,我是C程序员,因此下面可能会有一些语法错误 . 但是,希望我的观点足以让任何错误变得非常重要 .

    你得到段错误的原因是你将指针作为参数传递给函数时误解了发生了什么 .

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

    int main(void){
        int i;
    
        setInteger(i);
    
        printf("%d\n", i);
    
        return 0;
    }
    
    void setInteger(int n){
        n = 12;
    }
    

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

    如果程序被替换为

    int main(void){
        int i;
    
        setInteger(&i);
    
        printf("%d\n", i);
    
        return 0;
    }
    
    void setInteger(int *n){
        *n = 12;
    }
    

    那么 i 输出的值将是 12 .

    在您的程序中发生同样的事情,您正在传递指针 by 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";
        }
    
    }
    

    's, unfortunately, not the end of your problems. Although you'已为您的 myName 对象分配内存,您尚未为字符数组分配内存 .

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

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

    请注意:

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

相关问题