2

I have been trying to create a dynamically allocated array of struct type label and have been failing miserably. In my .h file, I have:

    typedef struct _label {
            char name[256];
            char type[256];
            int address;
} label;

and in my .c file, I have this at the top:

    label* allLabels = (label*) malloc(sizeof(label) * 10); // line 10
    int arrayIndex = 0;

and finally, I have a function in the same .c file that is meant to add these struct objects to the array to be used by other methods in the file:

    void addLabel(char line[], char type[], int addr) {
            label database;
            database.name = line; // line 805
            database.type = type; // line 806
            database.address = addr;
            allLabels[arrayIndex] = database;
            arrayIndex++;
        }

Basically I just want to have a collection of accessible labels. Can someone help me understand what I'm doing wrong?

I get these errors, and I haven't forgotten any of the necessary #include statements either:

formatBuilder.c:10:3: error: initializer element is not constant
formatBuilder.c: In function 'addLabel':
formatBuilder.c:805:18: error: incompatible types when assigning to type 'char[256]' from type 'char *'
formatBuilder.c:806.18: error: incompatible types when assigning to type 'char[256]' from type 'char *'
3
  • Array aren't pointers. You can't use = operator to assign a new value to an array. Commented Apr 26, 2013 at 4:16
  • What is database here in your code? Commented Apr 26, 2013 at 4:18
  • database is the name of my label object Commented Apr 26, 2013 at 4:33

2 Answers 2

5

You can't assign to char arrays like that, you need one of the string operations, such as:

strcpy (database.name, line);  // or "->" if database is pointer

(preferably checking the length beforehand to ensure no buffer overflow, or using a safer function depending on your needs).

It's also bad form to cast the return value from malloc in C since it can hide certain subtle errors. It's acceptable if your code has to also compile in C++ but you just need to ensure you have the correct prototype in scope.


In terms of the initialisation error, I suspect that you have the declaration at file level (outside of any function). This means you can't use a function call to initialise it since it has static storage duration and wants to be set before any code runs.

You can get around that problem thus:

// At file level:

label* allLabels = NULL;

// In your function:

void addLabel(char line[], char type[], int addr) {
    if (allLabels == NULL) {
        allLabels = malloc (sizeof(label) * 10);
        if (allLabels == NULL) {
            // malloc failed, do something to recover.
        }
    }
    // And we don't need local storage here, hit the array directly.

    strcpy (allLabels[arrayIndex].name, line);
    strcpy (allLabels[arrayIndex].type, type);
    allLabels[arrayIndex].address = addr;
    arrayIndex++;
}

This uses a constant initialiser NULL to set the value and you then just need to ensure it's allocated before the first time you use it.

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

2 Comments

Ah, awesome! That fixed the errors at 805 and 806. I still have the initializer error, but I'm one step closer. Thank you!! Is that caused by my casting of malloc? Or is that something else entirely?
@Laurence, sorry, didn't actually see that bit. Updated answer to cover that as well.
1

I suggest to use memcpy.

memcpy(&allLabels[arrayIndex], &database, sizeof(label));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.