Faulk
Faulk

Reputation: 1

Why are these dynamically allocated arrays different?

I have two arrays. They should start as the same thing, then I'll change one, and use both in some calculations. But (!) they don't start as the same thing. This is basically what I'm trying to do (I think):

int main() {

    int* arr1 = (int *) malloc( sizeof(int) * 7 );

    int* arr2 = (int *) malloc( sizeof(int) * 7 );

    for (int i=1; i<7; i++) {
        *(arr1 + ( sizeof(int) * i )) = i;
        *(arr2 + ( sizeof(int) * i )) = i;
    }

    // print the arrays

    // they should be the same, but...

    // arr1 is { 1, 2, 3, 4, 5, 6, 7 }

    // arr2 is { 4, 5, 6, 7, 5, 6, 7 }

}

I've printed the arrays as they're building up, and there is behavior that I cannot explain (but assume has to do with the fact that dynamically allocated arrays are put on the heap and not the stack, though I don't know what this means).

arr1 builds up like this, even though it turns out correct in the end:

1: {1,2,0,0,0,0,0}

2: {1,2,0,1,2,0,0}

3: {1,2,3,1,2,3,0}

4: {1,2,3,1,2,3,0}

5: {1,2,3,4,2,3,4}

6: {1,2,3,4,5,3,4}

7: {1,2,3,4,5,6,4}

8: {1,2,3,4,5,6,7}

And arr2 like this (the problem one):

1: {1,2,0,0,0,0,0}

2: {1,2,3,0,0,0,0}

3: {4,2,3,4,0,0,0}

4: {4,5,3,4,5,0,0}

5: {4,5,6,4,5,6,0}

6: {4,5,6,7,5,6,7}

Seems to me that when I reach the 4th element, it starts modifying two elements at each iteration.

Idk. Any help in understanding this would be greatly appreciated.

Here is my code in full (its awful I know). rankings and rankings1 are the arrays in question:

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



int main(){
    // Declare array of topics

    // need to remove these [] by using malloc again, and then hard coding each element
    char* topics[7] = {
        "Marine Conservation", "Climate Change", "Large-Scale Conflict/War",
        "Government Accountability", "COVID-19", "Curing Cancer", "Unemployment"
    };

    // declare other variables

    int rate, totalRating, i, j, respondents=0;

    double avg;

    // Declare array of responses

    //int responses[7][10];
    int* responses = malloc(sizeof(int)*70);
    int input_counter = 0;
    int user_input = 1;
    do {
        
        //printf("Person %d:\n", (i+1));
        printf("Please rate each topic from 1-10:\n");
        for(int i=0; i<7; i++){
            printf("%s: ", *(topics+(i*sizeof(char))));
            int rate;
            while(1){
                scanf(" %d", &rate);
                if(rate<0 || rate>10){
                    printf("Your rating must be between 1-10. Please try again:");
                    continue;
                }
                else break;
            }
            *(responses+(input_counter*sizeof(int))+(i*sizeof(int))) = rate;
        } 
        input_counter++;
        printf("Would you like to input response from another person?  1 for yes, 0 for no.");
        scanf(" %d", &user_input);
    } while(input_counter < 10 && user_input != 0);
    printf("here yo");
    int* rankings = (int *) malloc(sizeof(int)*7);
    int* rankings1 = (int *) malloc(sizeof(int)*7);
    printf("\nsize of int is: %d\n",sizeof(int));
    printf("%d is 28 away from %d", rankings,rankings1);

    // Print the array along with the average rating for each topic
    int highest_rated = 0, lowest_rated = 0;
    int highest_rated_points = 0;
    int lowest_rated_points = 11;
    //int* sorted_topics = (int *) malloc(sizeof(int)*7);
    for(i=0; i<7; i++){
        
        int cat_respond = 0;
        totalRating = 0;


        printf("%-20s: ", *(topics+(i*sizeof(char))));
        for(j=0; j<input_counter; j++){
            //printf("total rating is:%d  ",*(responses+(sizeof(int)*i)+(sizeof(int)*j)));
            totalRating += *(responses+(sizeof(int)*i)+(sizeof(int)*j));
            printf("%d \t",*(responses+(sizeof(int)*i)+(sizeof(int)*j)));
            cat_respond++;
        }
        // do highest/lowest rated calc
        if (highest_rated_points < totalRating) {
            highest_rated_points = totalRating;
            highest_rated = i;
        } 
        if (lowest_rated_points > totalRating) {
            lowest_rated_points = totalRating;
            lowest_rated = i;
        }
        printf("TotalRating %d at i is: %d", totalRating, i);
        //*(sorted_topics+(sizeof(int)*i)) = totalRating;
        *(rankings+(sizeof(int)*i)) = totalRating;
        *(rankings1+(sizeof(int)*i)) = totalRating;
        printf("the new element is: %d",*(rankings1+(sizeof(int)*i)));
        // do avg calc
        float avg = totalRating/cat_respond;
        printf("Avg: %.2f\n",avg);
        printf("arr is now: \n");
        for(int k=0;k<7; k++){
            printf("k is : %d thing is : %d",k, (sizeof(int)*k));
            printf("here is: %d\n", *(rankings1 + (sizeof(int)*k) ) );
         }
        
    }

    // display highest/lowest
    printf("The highest rated issue was: %s with a total rating of: %d\n", *(topics+(sizeof(char)*highest_rated)), highest_rated_points);
    printf("The lowest rated issue was: %s with a total rating of: %d\n", *(topics+(sizeof(char)*lowest_rated)), lowest_rated_points);

    // do sorting  - adapted from https://www.sanfoundry.com/c-program-sort-array-descending-order/
    printf("starting arry is :\n");
    for(int i=0; i<7; i++){
        printf("i is : %d",i);
        printf("here is: %d\n", *(rankings1+(sizeof(int)*i)));
    }
    for (int i = 0; i < 7; i++) 
    {
        for (int j = i + 1; j < 7; j++) 
        {
            if (*(rankings1+(sizeof(int)*i)) < *(rankings1+(sizeof(int)*j))) 
            {
                int a = *(rankings1+(sizeof(int)*i));
                *(rankings1+(sizeof(int)*i)) = *(rankings1+(sizeof(int)*j));
                *(rankings1+(sizeof(int)*j)) = a;
                printf("made swaping, array is now:\n");
                for(int i=0; i<7; i++){
                    printf("i is : %d",i);
                    printf("here is: %d\n", *(rankings1+(sizeof(int)*i)));
                }
            }
        }
    }
    for(int i=0; i<7; i++){
        printf("i is : %d",i);
        printf("here is: %d\n", *(rankings1+(sizeof(int)*i)));
    }
    
    printf("The issues ranked from highest to lowest are:\n");
    int curr_max;
    for (int i=0; i<7; i++) {
        int topic_num = 0;
        curr_max = *(rankings1+(sizeof(int)*i));
        for (int j=0; j<7; j++) {
            if (*(rankings+(sizeof(int)*j)) == curr_max) {
                topic_num = j;
                // *del* the element
                *(rankings+(sizeof(int)*j)) = -1;
                break;
            }
        }
        printf("%d: %s with a total rating of %d\n",i+1,*(topics+(sizeof(char) * topic_num)),curr_max); 
    }


    // total respondents calc
    for (int i=0; i<10; i++) {
        if (*(responses+(sizeof(int)*i)) != 0) 
            respondents++;
    }
    printf("Total respondents: %d\n", respondents);

    free(responses);
    free(rankings);
    free(rankings1);
}

Upvotes: 0

Views: 66

Answers (1)

eerorika
eerorika

Reputation: 238351

You observed the behaviour that you did because the behaviour of the program is undefined. The last valid index in an array of 7 int objects is 6. But you write all the way into index sizeof(int) * 7 which assuming a 4 byte int is 28. 28 is greater than 6, so it is outside the bounds of the buffer.

P.S. Use the subscript operator to make the code readable. Here is a correct way to assign the elements of the arrays with sequence 1, 2, 3, ...:

int count = 7;
int* arr1 = malloc(sizeof(int) * count;
int* arr2 = malloc(sizeof(int) * count);
for (int i=0; i<count; i++) {
    arr1[i] = i + 1;
    arr2[i] = i + 1;
}

Upvotes: 1

Related Questions