NewGradDev
NewGradDev

Reputation: 1034

Using strcpy() with arrays of structs (and their elements) doesn't work

Working on a homework assignment but have been stuck on this problem for the past 2 hours. I basically have a struct called courses. The struct is defined as so:

typedef struct {
  int crn;
  char course[STR_SIZE];
  char course_number[STR_SIZE];
} courses;

I have a dynamically allocated array that contains these structs, called courses_array. I also have another temp array called temp_courses_array. I'm trying to copy the contents of the structs in courses_array to the structs in temp_courses_array by using strcpy(); ie. the course_number element in the i-th position of courses_array should be copied as the course_number element in the i-th position of temp_courses_array. For some reason, whenever I invoke the strcpy() function, the same four elements keep getting copied into temp_courses_array. Here's my code (the output is below the code):

void resize (int **p_size, courses **courses_array)
{
  int i;
  courses *temp_courses_array;
  **p_size = **p_size*2;

  //Initialize the temp array.
  initialize(p_size, &temp_courses_array);

  printf("----------------BEGIN EXPECTED OUTPUT----------------\n");

  for (i = 0; i < ((**p_size)/2); i++)
  {
    printf("%d %s\n", i, ((*courses_array)[i]).course_number);
  }

  printf("----------------BEGIN ACTUAL OUTPUT------------------\n");

  for (i = 0; i < ((**p_size)/2); i++)
  {
    printf("%d %s\n", i, ((*courses_array)[i]).course_number);
    strcpy((temp_courses_array[i]).course_number, ((*courses_array)[i]).course_number);
  }

  free(*courses_array);
  *courses_array = temp_courses_array;   

}//resize()

I'm at a loss as to why this could be happening. It seems that I'm somehow modifying courses_array by using the strcpy() function... which makes no sense since strcpy() should leave the original array intact. Am I correct in this assumption or am I missing anything? I guess another option would be to copy the entire struct into the temp_courses_array instead of each individual element. I'm not sure how to do that though. If someone could point me in the right direction, that'd be great. Thanks!

Here's the output:

--------------BEGIN EXPECTED OUTPUT----------------
//The first element is the iteration in the loop (i).
0 052
1 123
2 170
3 100B
4 100B
5 106
6 106
7 112
8 136
9 171B
10 171B
11 189C
------------BEGIN ACTUAL OUTPUT---------------
//Notice the repeating elements.
0 052
1 123
2 170
3 100B
4 052
5 123
6 170
7 100B
8 052
9 123
10 170
11 100B

EDIT: Here's my initialize() function:

void initialize(int **p_size, courses **courses_array)
{ 
  *courses_array = (courses *) malloc((**p_size) * sizeof(courses *));
}//initialize()

Upvotes: 1

Views: 1023

Answers (1)

paddy
paddy

Reputation: 63471

I don't see anything obvious that would cause this. You should show your initialize function. Perhaps you're messing up or overlapping the two arrays.

I'll answer the second part of your question, because I think that's better for you:

I guess another option would be to copy the entire struct into the temp_courses_array instead of each individual element.

Yes. Because the struct is plain-old-data (POD), you can just copy it like any other inbuilt type:

for (i = 0; i < ((**p_size)/2); i++)
{
    temp_courses_array[i] = (*courses_array)[i];
}

However, you may still have an issue with initialize so you still need to fix it.


Note that you don't normally have to do this reallocate-copy-free process. Instead, you can use realloc to resize a block of memory, and it will handle the details. If it can enlarge the block without copying, it will. If it needs to create a new one and copy the old one in, it will.

So your function could be as simple as this:

void resize (int **p_size, courses **courses_array)
{
    courses *temp = realloc( *courses_array, **p_size * 2 );
    if( temp ) {
        **p_size *= 2;
        *courses_array = temp;
    }
}

Follow-up

Since you posted your initialize function...

void initialize(int **p_size, courses **courses_array)
{ 
    *courses_array = (courses *) malloc((**p_size) * sizeof(courses *));
}

This is allocating an array large enough to hold a bunch of pointers. Use sizeof(courses) instead of sizeof(courses*) and it will fix. Currently you're overflowing your array (because your structure is larger than a pointer) and you are getting undefined behaviour.

Upvotes: 3

Related Questions