C - realloc () for tokenized array: SIGABRT signal

On line 56, I'm trying to resize the array:

tokenArray = (char**) realloc(tokenArray, tokSize * (sizeof(char))); 

I get an error message:

(11972,0x7fff7ca4f300) malloc: * error for object 0x100105598: incorrect checksum for the freed object - the object was probably changed after it was released. * set breakpoint in malloc_error_break for debugging

This is a programming assignment for a class, I was specifically instructed to dynamically allocate my arrays and then expand as needed. Many times I searched for another thread on the same, which is not too advanced for me to understand, until I succeeded ... So I hope that I can get some help. Thank you Here is my code:

 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_ROW_SIZE 81 void strInput(char str[], int numElem); int main(int argc, const char * argv[]) { printf("Enter a string of any number of integers separated by spaces or tabs.\n"); printf("Maximum string length is 80 characters.\n"); printf("Enter an empty string to conclude input.\n"); int arrSize = 10, tokSize = 10, i = 0, j = 0; char** inputArray = malloc(arrSize * (sizeof(char))); char** tokenArray = malloc(tokSize * (sizeof(char))); do { inputArray[i] = malloc(MAX_ROW_SIZE * sizeof(int)); strInput(inputArray[i], arrSize); if ((inputArray[i][0] != '\0') && (i == (arrSize - 1))) { arrSize = arrSize * 2; inputArray = (char**) realloc(inputArray, arrSize * (sizeof(char))); } while (inputArray[i][j] != '\0') { printf("%c", inputArray[i][j]); j++; } j = 0; i++; } while (inputArray[i-1][0] != '\0'); i = 0; while (inputArray[i][0] != '\0') { if ((tokenArray[j] = strtok(inputArray[i], " \t"))) j++; while ((tokenArray[j] = strtok(NULL, " \t"))) { if (j == (tokSize - 1)) { tokSize = 2 * tokSize; //This is the line where I get the error tokenArray = (char**) realloc(tokenArray, tokSize * (sizeof(char))); } j++; } i++; } printf("printing the tokenized arrays: "); for (i = 0; i < j; i++) printf("%s ", tokenArray[i]); free(inputArray); free(tokenArray); return 0; } void strInput(char str[], int numElem) { int j, k = 0; j = k; while ((str[k] = getchar()) != '\n') { k++; } if (str[k] == '\n') str[k] = '\0'; } 
+5
source share
1 answer

1. Do not follow the result of malloc and friends .

It is useless at best and dangerous at worst.

2. Remember the size of the malloc 'ing.

 char** inputArray = malloc(arrSize * (sizeof(char))); 

This makes no sense and is probably random. Typically, the type that you are malloc 'ing and the pointer pointing to the resulting repository should differ only in one indirect. Ie:

 char** inputArray = malloc(arrSize * sizeof(char*)); // ^^ Double-pointer vs Single pointer ^ 

Best rule of thumb, let the compiler figure this out. sizeof can infer the type that it should measure from an expression.

 char **inputArray = malloc(arrSize * sizeof(*inputArray)); 

This works because the sizeof operand is an invaluable context. The pointer will not actually be dereferenced, only its type will be displayed.
Note: sizeof parentheses are not needed around the expression, but I left them for clarity. Remove them as soon as you feel comfortable.

3. Verify that the selection was successful.

malloc and friends will return NULL in case of problems. You have to check it out.

4. Fix realloc

 inputArray = realloc(inputArray, /*...*/); 

It is not right. As mentioned above, if realloc fails, it will return NULL and do nothing. This means that inputArray is still pointing to the previous store. That is, until you have exceeded this pointer with the just returned NULL realloc and leaked the repository mentioned. Unfortunately.

Always save, verify, and then assign the realloc result.

 char **inputArray_ = realloc(inputArray, /*...*/); if(!inputArray_) { /* Allocation failure, handle it and break out */ } inputArray = inputArray_; 
+5
source

All Articles