0

I just started learning C programming and practicing dynamic array and malloc and realloc. I'm using Visual Studio and the code is in file extension .c But I do not know why realloc is causing the error message "HEAP[Assignment1Start.exe]: Heap block at 01217FA8 modified at 01217FE8 past requested size of 38" Please ctrl-f this phrase " Here I want to realloc " It will direct you to the line where it's causing the error message.

    #define _CRT_SECURE_NO_DEPRECATE 
    #include<stdio.h>
    #define _CRT_SECURE_NO_WARNINGS

    #define _NO_DEBUG_HEAP 1

    int main()
    {
        FILE *ptr_file;
        FILE *ptr_file2;
        char buf[1000]; //1000 characters array. //if label[10] = "Single"; then label[2] outputs "n"// label[6] outputs "\0" // label[7] outputs " " empty space

        char *vArray2; //is as pointer to a character, to which you allocated memory to hold exactly 1 character.
        int NoOfTasks = 0;
        char **ArrayNo;
        char **ArrayTemp;
        //#define ArrayCapacity 15
        int ArrayCapacity = 20;
        #define ID_LEN 10
        int i;
        int power = 1;
        int quitbtn = 8;


        ptr_file = fopen("output.txt", "r");
        if (!ptr_file)
            return 1;

        ArrayNo = (char*)malloc(ArrayCapacity*sizeof(char)); //allocate some memory that your pointer will point to. //You should always make it point to something or you can allocate some memory that your pointer will point to.

        ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
        strcpy(ArrayNo[NoOfTasks], "Quit\n");
        NoOfTasks += 1;

        while (fgets(buf, 1000, ptr_file) != NULL) //fgets adds the \n to the end of each line it reads and stores it in buf //outputs to command prompt//If the end-of-file (EOF) is reached the fgets function will return a NULL value
        {

            ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
            strcpy(ArrayNo[NoOfTasks], buf);

            NoOfTasks += 1;
        }

        while (power == 1){

            for (int r = 0; r < NoOfTasks; r++){

                    printf("%d %s", r,ArrayNo[r]);

            }

            printf("\n Please enter the task order number");

            int userInputInt1 = 0;

            scanf("%d", &userInputInt1);

            if (userInputInt1 != 0) //0 is quit NoOfTasks-1
            {
                printf("\n %s (1)Add task (2) Remove Task (3)Replace Task", ArrayNo[userInputInt1]);
                int userInputInt2 = 0;
                scanf("%d", &userInputInt2);
                //int result = atoi(userInput2); // convert string to int

                if (userInputInt2 == 3)
                {
                    printf("\n Type in new task");
                    char userInput3[30];
                    scanf("%s", &userInput3);

                    if (userInput3 != " "){

                        int n;

                        printf("\n %s Replaced with %s \n", ArrayNo[userInputInt1], &userInput3);

                        strcpy(ArrayNo[userInputInt1], &userInput3);
                        strcat(ArrayNo[userInputInt1], "\n");
                    }
                }
                if (userInputInt2 == 2) //remove
                {
                    int n;
                    NoOfTasks -= 1;
                    for (int c = userInputInt1; c < NoOfTasks; c++){
                        printf("\n %s Replaced with %s", ArrayNo[userInputInt1], ArrayNo[c + 1]);
                        ArrayNo[c] = ArrayNo[c + 1];
                    }
                }
                if (userInputInt2 == 1) //add
                {
                    printf("\n Add a task");
                    char userInput4[30];
                    scanf("%s", &userInput4);


                    ArrayCapacity += 1;// increase ArrayCapacity by 1 because a new task is added
                    ArrayNo = (char**)realloc(ArrayNo, (ArrayCapacity* sizeof(char*))); // here I want to realloc memory for new element of the array ArrayNo when a new task is added
                    ArrayNo[NoOfTasks] = malloc((ID_LEN + 1) * sizeof(char));
                    strcpy(ArrayNo[NoOfTasks], &userInput4);

                    NoOfTasks += 1;
                }

            }
            if (userInputInt1 == 0) //8 is quit NoOfTasks-1
            {
                ptr_file2 = fopen("WriteTo2.txt", "w");
                if (!ptr_file2)
                    return 1;
                for (int r = 1; r < NoOfTasks; r++){

                    fprintf(ptr_file2, "%s\n", ArrayNo[r]);
                }
                printf("\n You quit the program");
                fclose(ptr_file2);
                fclose(ptr_file);
                power = 0;
            }
        }


        getchar();
        getchar();
        getchar();
        return 0;
    }
SpiderWeb
  • 79
  • 6

1 Answers1

0

The initial allocation is incorrect.

ArrayNo is char**. And you do

ArrayNo = (char*)malloc(ArrayCapacity*sizeof(char)); 

This allocates only ArrayCapacity bytes (sizeof(char) is 1). And the array actually needs much more, ArrayCapacity*4 or ArrayCapacity*8 bytes (sizeof(char*) is 4 or 8; let's say it's 4, then ArrayNo[5] starts at offset 4*5 which is already beyond the allocated region). So, when you fill in the array, you overwrite some bytes of memory which you are not allowed to, and luckily realloc (in debug mode) has a check for this and stops execution as soon as it notices that there was memory corruption.

nullptr
  • 11,008
  • 1
  • 23
  • 18