首页 > 解决方案 > 为什么这些动态分配的数组不同?

问题描述

我有两个数组。它们应该从相同的东西开始,然后我会改变一个,并在一些计算中使用它们。但是(!)它们的开始并不相同。这基本上就是我想要做的(我认为):

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 }

}

我已经打印了正在构建的数组,并且存在我无法解释的行为(但假设与动态分配的数组放在堆上而不是堆栈上的事实有关,尽管我不知道这是什么意思)。

arr1 是这样构建的,即使它最终证明是正确的:

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}

像这样的 arr2 (问题之一):

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}

在我看来,当我到达第 4 个元素时,它开始在每次迭代中修改两个元素。

同上。任何帮助理解这一点将不胜感激。

这是我的完整代码(我知道它很糟糕)。排名和排名1 是有问题的数组:

#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);
}

标签: arrayscpointersdynamic-memory-allocation

解决方案


您观察到您所做的行为是因为程序的行为未定义。7 个对象的数组中的最后一个有效索引int是 6。但是您一直写入索引sizeof(int) * 7,假设 4 字节int为 28。28 大于 6,因此它超出了缓冲区的范围。

PS 使用下标运算符使代码可读。这是使用序列 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;
}

推荐阅读