0

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.

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. 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. 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.

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. 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 :)

4
  • Is there a specific question you have? Commented Dec 29, 2013 at 20:23
  • clicked 'submit' accidentally before finishing the question. Commented Dec 29, 2013 at 20:25
  • 1
    instead of struct myStruct *q = malloc(sizeof(struct myStruct *));, you should use struct myStruct *q = malloc(sizeof(struct myStruct));. I would suggest to use a linked list instead of reallocating everytime. Commented Dec 29, 2013 at 20:26
  • I should build friendships etc and I get commands by student names, and I use strucure names for lists of friendships. so linked lists may be difficult to use Commented Dec 29, 2013 at 20:40

5 Answers 5

3

In your code, the following line allocates enough memory for a pointer to myStruct, not actually memory for the structure.

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. i.e. sizeof(struct myStruct) Hope this helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much :) This solves the allocating problem but I still have problems with reaching it.
I don't know what "reaching it" means. Is your program crashing? At what line?
You are right. I should have been explained it before. Edited the question.
1
#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;
}

4 Comments

I'm not familiar with strdup and atoi functions and I'm trying to write in ansi standards, are strdup and atoi functions are ansi standards?
@user3108849 atoi is present in the standard. strdup does not exist.
only one final question, what I can replace strdup with in ansi standards? I can't get the results without it.
@user3108849 I have added a definition of strdup.
1

As @Darren has pointed out, you are using heap incorrectly.

Another error in your code is: 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 *). Based on your later code for adding using realloc, I deem that it is the former.

Comments

1

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. Thus you need to something along the lines of struct myStruct **students = malloc(N * sizeof(struct myStruct *)); where N is something you choose.

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.

Comments

1

Do you really want to use an int pointer for the "bornYear"?

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 e.g,

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.

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:

  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.

  2. By having to assign a generous length to avoid the above point, you do effectively waste a little space.

3 Comments

@user3108849 Please also note my discussion of using just the char* instead of a char[]. I edited my original post to reflect this.
I edited the year thing as normal integers instead of pointers. but when I try to change the name and school pointers to arrays I faced with too many errors so I don't think I can do that. What are the disadvantages of using pointers except dynammic memory allocation ?
@user3108849 Sorry, probably partly my mistake. You specify the size of the array next to the name not the declaration of the data type, per standard C nomenclature. Corrected above.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.