简体   繁体   English

用C处理结构数组

[英]Handling with array of structures in C

Sorry for long question but I am about to go crazy here. 抱歉,很长的问题,但是我在这里疯了。

I am trying to write a little simulation of a social network in c language. 我正在尝试用C语言编写一个社交网络的模拟。

I'm trying to create an array of structures which each one is a user. 我正在尝试创建一个结构数组,每个结构都是一个用户。

For 6 days, I'm trying to write the part that the program adding users and reaching the logs afterwards, and I couldn't. 在6天的时间里,我试图编写程序添加用户并随后到达日志的部分,但我做不到。 So I'm about to lose my mind over here. 所以我将在这里失去理智。

struct myStruct { /* This is a global variable */
     char *studentName;
    int *bornYear;
    char *school;
};

then in the main function, I create a pointer such as; 然后在主函数中,我创建一个指针,例如;

struct myStruct** students = malloc (sizeof(struct myStruct ));
int counter = 0; /* the counter of students */

by if-else if and switch-case chains, I categorize the commands. 通过if-else if和switch-case链,我对命令进行了分类。 when it is asked to add a new user, a realloc the array I created: 当要求添加新用户时,重新分配我创建的数组:

students = realloc(students, (counter+1) * sizeof (struct students));
students[counter] = adding (*command, counter);
counter++;

the function is here: 函数在这里:

struct myStruct adding (char theCommand[], int i){
    struct myStruct *q = malloc(sizeof(struct myStruct *)); // I get a warning for this allocation
    char *irrelevantChar = strtok(theCommand[], ";");
    q->studentName  = strtok(NULL, ",");
    q->bornYear= strtok(NULL, ",");
    q->school= strtok(NULL, ",");
    return q;

I am sure that strtok functions are working right. 我确信strtok函数正常运行。

When I try to reach these structures, the program gives error on run-time (stoppes working on windows, segmentation fault on ubuntu) or I see random irrelevant data etc. I am working with this for 6 days so I have seen lots of errors. 当我尝试到达这些结构时,程序在运行时给出错误(在Windows上运行Stoppes,在ubuntu上出现分段错误),或者我看到随机无关的数据等。我正在使用6天,因此我看到了很多错误。 But I couldn't find the right way to create and access these structures. 但是我找不到创建和访问这些结构的正确方法。

In another command situation; 在另一种指挥情况下;

"command character" John Smith,George Lucas // names are just for example :)

I just wrote the following code for this situation: 我只是针对这种情况编写了以下代码:

printf ("\n\n%s", myStruct[0]->school;

This is just a random order, just to show that I cannot access it. 这只是一个随机命令,只是为了表明我无法访问它。

The output must be "Oxford University" or something. 输出必须是“牛津大学”之类的。 Instead, I get the exactly following output: 相反,我得到以下确切的输出:

ge Lucas

So some random data. 所以一些随机数据。 I don't know what is wrong with here either. 我也不知道这有什么问题。

I must build friendships etc. so I must have access to every single structure I created. 我必须建立友谊等。因此,我必须可以访问我创建的每个结构。

Thanks :) 谢谢 :)

In your code, the following line allocates enough memory for a pointer to myStruct , not actually memory for the structure. 在您的代码中,以下行为指针 myStruct分配了足够的内存,而不是为该结构实际​​分配了内存。

struct myStruct *q = malloc(sizeof(struct myStruct *)); 

You then start to dereference that pointer, so you are accessing unallocated memory at this point: 然后,您开始取消对该指针的引用,因此此时您正在访问未分配的内存:

q->studentName  = strtok(NULL, ",");
q->bornYear= strtok(NULL, ",");
q->school= strtok(NULL, ",");

I can't say there aren't other bugs in your code, but you need to start by allocating sufficient memory. 我不能说您的代码中没有其他错误,但是您需要首先分配足够的内存。 ie sizeof(struct myStruct) Hope this helps. sizeof(struct myStruct)希望这会sizeof(struct myStruct)帮助。

From the looks of it, the problem seems to be with these blocks of code: 从外观上看,问题似乎出在这些代码块上:

struct myStruct **students = malloc(sizeof(struct myStruct));

and: 和:

students = realloc(students, (counter+1) * sizeof (struct students));
students[counter] = adding (*command, counter);
counter++;

You are telling malloc to allocate to students the amount of space equal to the size of struct myStruct but that's probably not what you want because it seems you want students to be an array of pointers to struct myStruct objects. 您正在告诉mallocstudents分配等于struct myStruct大小的空间,但这可能不是您想要的,因为似乎您希望学生成为struct myStruct对象的pointers数组。 Thus you need to something along the lines of struct myStruct **students = malloc(N * sizeof(struct myStruct *)); 因此,您需要遵循struct myStruct **students = malloc(N * sizeof(struct myStruct *)); where N is something you choose. N是您选择的东西。

Then your code can go about looking like this: 然后您的代码可以像这样:

struct myStruct **students = malloc(N * sizeof(struct myStruct *));
int counter = 0;
    .
    .
    .
students[counter] = adding(*command /* Make sure command isn't already a char* */, counter);
counter++;

Since you are doing a malloc in adding and returning the pointer to the malloc'ed space you do not need realloc. 由于在adding和返回指向malloc的空间的指针时正在执行malloc ,因此不需要重新分配。

As @Darren has pointed out, you are using heap incorrectly. 正如@Darren指出的那样,您使用的堆不正确。

Another error in your code is: struct myStruct** students = malloc (sizeof(struct myStruct )); 代码中的另一个错误是: struct myStruct** students = malloc (sizeof(struct myStruct ));

Now either students should be of type struct myStruct * or malloc should be called with sizeof(struct myStruct *) . 现在,要么学生应该是struct myStruct *类型,要么应该使用sizeof(struct myStruct *)调用malloc。 Based on your later code for adding using realloc, I deem that it is the former. 根据您以后使用realloc添加的代码,我认为它是前者。

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

typedef struct myStruct {
    char *studentName;
    int bornYear;
    char *school;
} Student;


Student adding (char theCommand[]){
    struct myStruct q;
    char *irrelevantChar = strtok(theCommand, ";");
    q.studentName  = strdup(strtok(NULL, ","));
    q.bornYear= atoi(strtok(NULL, ","));
    q.school= strdup(strtok(NULL, ","));
    return q;
}

int main(void){
    char command[] = "junk;George Lucas,1944,University of Southern California";
    int counter = 0;
    Student *students = NULL;
    students = realloc(students, (counter+1) * sizeof (Student));
    students[counter++] = adding(command);

    printf("name   : %s\n", students[0].studentName);
    printf("school : %s\n", students[0].school);

    //deallocation:studentName, school
    //free(students);
    return 0;
}

char *strdup(const char *str){
    char *p = malloc(strlen(str)+1);
    if(p){
        strcpy(p, str);
    }
    return p;
}

Do you really want to use an int pointer for the "bornYear"? 您是否真的要为“ bornYear”使用int指针?

change to 改成

struct myStruct { /* This is a global variable */
    char  *studentName;
    int   bornYear;
    char  *school;
};

You probably also want to explicitly specify the length of the char* arrays eg, 您可能还想明确指定char *数组的长度,例如,

char[40] studentName

Hence 因此

struct myStruct { /* This is a global variable */
    char    studentName[40];
    int     bornYear;
    char    school[80];
};

You could leave school and studentName as a char pointer (char*) but by doing so you all you have within the struct is not the string itself but a pointer to a memory location outside the struct that you will need dynamically allocate in the heap using malloc and manipulate using the standard c string manipulation functions like strcpy etc. 您可以将school和studentName保留为char指针(char *),但这样做的话,您在struct中拥有的并不是字符串本身,而是指向该结构外部的存储位置的指针,您需要使用使用标准的c字符串操作函数(如strcpy等)进行malloc和操作。

By declaring the struct with a char array (otherwise known as a string), you do simplify the whole process and effectively keep the string within the struct but can potentially run into two issues: 通过使用char数组(也称为字符串)声明该结构,可以简化整个过程并有效地将该字符串保留在该结构中,但可能会遇到两个问题:

  1. There is potential for exceeding the size of the assigned array if your string is greater than the char[n - 1] (n - 1 due to the string terminating nul charcater \\0 ), this can be avoided by careful programming. 如果您的字符串大于char [n-1](由于字符串以nul charcater \\ 0终止,则n-1),则可能会超出分配数组的大小,可以通过仔细编程来避免这种情况。

  2. By having to assign a generous length to avoid the above point, you do effectively waste a little space. 通过为避免上述问题而分配足够的长度,可以有效地浪费一点空间。

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

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