c - 如何在 C 中使用双重结构的动态分配(malloc)?

标签 c malloc clang structure allocation

我想知道如何在 C 中使用具有双重结构的动态分配 (malloc)。

我想制作一个像这样表示的程序

Input Subject1 Name : Math

Input Subject2 Name : English

Input Taker1 Name : Kim

Input Taker2 Name : Park

Input Taker3 Name : John

Input Taker4 Name : David

Input Taker5 Name : Kelly

Input Taker6 Name : Fiona

Input Taker7 Name : Amanda

Input Taker8 Name : Sally

Input Taker9 Name : Lee

Input Taker10 Name : Kang

-RESULT-

Kim : Math, English

Park : Math, English

John : Math, English

David : Math, English

Kelly : Math, English

Fiona : Math, English

Amanda : Math, English

Sally : Math, English

Lee : Math, English

Kang : Math, English

这是我编写的代码,代表两个彼此相关的结构。

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

#define SNUM 2          
#define TNUM 10             

typedef struct subscore {           
    char cname[SNUM][20];       
    int score[SNUM];                
} sscore;

typedef struct Taker {              
    char *name;                         
    sscore score;                   
} tTaker;

...

void main() {
    tTaker **teta[TNUM];
    create_Taker(teta);

    printf("-RESULT-\n");
    print_Taker(tTaker ** teta);
    ...

    delete_Taker(teta);
}


void create_Taker(tTaker ** teta) {

    char str[80];
    int len;

    for (int i = 0; i < SNUM; i++) {
        printf("Input Subject%d Name : ", i + 1);
        gets_s(str, 80);
        len = strlen(str) + 1;      
        teta[i]->score.cname = (char **)malloc(sizeof(char)*len); // ERROR!     
        strcpy_s(tt[i]->score.cname, sizeof(char), str);    
    }

    for (int i = 0; i<TNUM; i++) {
        printf("Input Taker%d Name : ", i + 1);
        gets_s(str, 80);
        len = strlen(str) + 1;
        teta[i]->name = (char **)malloc(sizeof(char)*len);  
        strcpy_s(teta[i]->name, sizeof(char), str); 
    }
    getchar();  
}

...

void print_Taker(tTaker ** teta) {
        ...
}

void delete_Taker(tTaker **teta) {
    for (int i = 0; i < TNUM; i++) {        
        free(teta[i]->score.cname);         
        free(teta[i]->name);                    
    }
}

从代码中可以看到,结构体“tTaker”包含另一个结构体“sscore”。 为此,我编写了这样的代码:

void create_Taker(tTaker ** teta) {

    char str[80];
    int len;

    for (int i = 0; i < SNUM; i++) {
        printf("Input Subject%d Name : ", i + 1);
        gets_s(str, 80);
        len = strlen(str) + 1;      
        teta[i]->score.cname = (char **)malloc(sizeof(char)*len); // ERROR!     
        strcpy_s(tt[i]->score.cname, sizeof(char), str);    
    }

    for (int i = 0; i<TNUM; i++) {
        printf("Input Taker%d Name : ", i + 1);
        gets_s(str, 80);
        len = strlen(str) + 1;
        teta[i]->name = (char **)malloc(sizeof(char)*len);  
        strcpy_s(teta[i]->name, sizeof(char), str); 
    }
    getchar();  
}

但是,正如您从代码中看到的,由于这部分,出现了一些问题:

teta[i]->score.cname = (char **)malloc(sizeof(char)*len);//错误!

我编写这段代码是为了尝试制作一个动态分配函数...但是它有很多我无法解决的问题。我使用 Visual Studio 2017 作为 IDE,并且该程序由于该部分而打印了此错误消息。

warning C404

error C2106 : left value should be l-value.

遗憾的是,我的 Visual Studio 中的调试功能不起作用,因此我无法解决此问题...

我想让我的问题像我在介绍部分中展示的示例一样工作。

那部分有什么问题吗? 我想知道这个函数是否正常工作:

void delete_Taker(tTaker **teta) {} 

我需要你的大力帮助。谢谢。

这张图片代表了程序的内存是什么样子的..

enter image description here

最佳答案

** 是一个指向指针的指针。

示例:

int a;
int *x = &a;
int **y = &x;

这里a是变量。 x 是一个指针,具有 a 的地址。 y 是一个指向指针的指针,并且具有指针 x 的地址。

y 不能保存变量 a 的地址。即 int **y=&a; 无效。

类似地,如果我这样做 printf("%d",*y); 它将打印指针 x 的地址而不是 a 内的值。

好的,现在开始回答你的问题。

tTaker **teta[TNUM]; 是一个指向指针的指针,该指针可以保存任何指向 tTaker 的指针的地址。

在这一行中 teta[i]->score.cname = (char **)malloc(sizeof(char)*len); teta[i]->score.cname 无效,因为您无法访问 score.cname,因为 teta 不是指向 tTaker 的指针,而是指向指针的指针。

此外,您还没有初始化 tTaker **teta[TNUM]; ,创建指针并不意味着创建对象。您需要分配对象并将其分配给 teta..

关于c - 如何在 C 中使用双重结构的动态分配(malloc)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43306085/

相关文章:

无符号整数和有符号整数的比较运算

编译器之间 free/malloc 的兼容性

c++ - 为什么 Clang 将显式强制转换解释为隐式强制转换?

c - C语言中如何将两个数组字符串变成一个数组字符串

c - thread_create_running 导致我的整个计算机在 OSX 10.6 上重新启动

C - strpy、char*** 崩溃

c++ - 如果 malloc() 在同一位置分配内存,则访问已释放的指针可能会导致数据损坏,除非已释放的指针设置为 NULL

clang - 是否可以使用 llc 标志运行 clang

gcc - 使用brew 将 gcc 链接到 gcc-6

c - 如何从函数返回一个字符串到main()?