Realloc error in C - c

I've just started C read the man page but could not find the proper answer. So the code is below
void *p = malloc(10*sizeof(int));
int *q = p;
int NUMOFINT = 10;
for (int i = 0; i < NUMOFINT; i++){
printf("%i ", q[i]);
}
void *realloc(void *p, 20*sizeof(int));
for (int i = 0; i < 21; i++){
printf("%i ", q[i]);
and it is giving this error:
malloc.c: In function ‘main’:
malloc.c:31:24: error: expected declaration specifiers or ‘...’ before numeric constant
I did not quite understand that the size format was ok for malloc() but not ok for realloc. So how do I correct the error?
Edit:
so when I make it as:
void *morep = realloc(p, 20*sizeof(int));
int *q2 = morep;
for (int i = 0; i < 20; i++){
printf("%i ", q2[i]);
}
it prints out q2[11] as 135121

This
void *realloc(void *p, 20*sizeof(int));
is wrong. You want
p = realloc(p, 20*sizeof(int));
Incidentally, this line is also a problem (but will compile fine):
for (int i = 0; i < 21; i++){
You allocated p to 20*sizeof(int) bytes, so element 20 is past the end of the array. You want:
for (int i = 0; i < 20; i++){

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int *temp; /* To use with realloc, it's more secure */
void *p = malloc(10*sizeof(int));
int *q = p;
int NUMOFINT = 10;
/* dont forget to compile with -std=99 flag, if you use this kind of for loop */
for (int i = 0; i < NUMOFINT; i++){
printf("%i ", q[i]);
}
printf("\n");
/* It's more secure to use this kind of realloc */
temp = realloc (p, 20 * sizeof(int) );
if (temp == NULL)
{
fprintf(stderr,"Reallocation failed --> %s\n", strerror(errno));
free(p);
exit(EXIT_FAILURE);
}
else
{
p = temp;
}
/* Zeroing after realloc */
for (int i = NUMOFINT; i < 21; i++)
q[i] = 0;
for (int i = 0; i < 21; i++)
{
printf("%i ", q[i]);
}
printf("\n");
return 0;
}

realloc can tries to expand the existing memory block in heap, if its not possible it will allocate a new separate block of memory for the new size and it will copy the data from old memory block to the new memory block also.
So if realloc returns the address same as p then it just expands the old memory block. Or else we have to free the old memory block and start using the new memory block returned by realloc.
#define NUMOFINT 10
#define NUMOFINT_NEW 20
void *p = malloc(NUMOFINT * sizeof(int));
int *q = p;
void *temp = NULL;
for (int i = 0; i < NUMOFINT; i++)
{
printf("%i ", q[i]);
}
temp = realloc(p, NUMOFINT_NEW * sizeof(int));
if (temp == NULL)
{
exit(0);
}
else if (temp != p)
{
free(p);
p = temp;
}
//else temp is equal to p
for (int i = 0; i < NUMOFINT_NEW; i++)
{
printf("%i ", q[i]);
}
Here q[0] to q[9] will have the values(0, 1, 2..9) assigned, and the rest (q[10] to q[19]) will have garbage value. We have not memset the newly allocated memory to 0 also.
you can memset also before for loop,
memset((q + NUMOFINT), 0, (NUMOFINT_NEW - NUMOFINT));
Mistakes in your program are
1) compilation error because
void *realloc(void *p, 20*sizeof(int)); This statement doesn;t looks like a function call.
2) for (int i = 0; i < 21; i++) - After memory is realloced to 20 elements, you can access only upto 19th, accessing 20th may leads to crash(undefined behaviour).
3) it prints out q2[11] as 135121 - Newly reallocated memory is neither memset to 0 nor assigned any meaningful values.

Related

C - malloc: Incorrect checksum for freed object 0x7fae81505280:

I have a program that takes as input an integer n followed by (n+1) lists. The integers in these lists are used to perform an arbitrary mathematical operation. Input will look like this for example:
5
2: [2,-2]
3: [1,-1,1]
4: [-5,3,-5,-1]
5: [2,-1,-1,-5,-2]
6: [-5,4,-3,3,4,-3]
10: [-23,9,-15,-22,5,6,-21,-15,-22,4]
The desired output is:
25: [-2300,9870,-23594,42570,-55674,58618,-44668,17698,7396,-18046,4346,25258,-50964,54140,-34960,3790,14120,-19116,16540,-9380,4494,1702,-1824,-64,48]
The way I read these lists is that I perform the operation as I read. In other words, I read a line and then perform an operation and then read the next line instead of reading every line and then performing the operation all in one go.
h_init is the array I use to "accumulate" my intermediate results in.
h_next is used to store the next list that is read.
temp is to store the calculated results within each iteration of the for loop.
At the end of each iteration I will copy temp into h_init.
After the mathematical operation is performed, the length of the result increases therefore I use realloc to extend the length of h_init at the end of every iteration.
When I run my code with input I get the following error:
malloc: Incorrect checksum for freed object 0x7fae81505280: probably modified after being freed.
Corrupt value: 0xffffffea0000000c
So I understand that this error is saying that my error is most likely trying to access an array after I've freed it but I don't understand how and where this is happening. In my code you can see that I instantiate h_next and temp at the very start of the for loop and then I free them both just before the current iteration ends.
So my question is: where am I supposed to free temp and h_next then to avoid this error?
(See code below)
void *safeMalloc(int sz) {
void *p = calloc(sz, 1);
if (p == NULL) {
fprintf(stderr, "Fatal error: safeMalloc(%d) failed.\n", sz);
exit(EXIT_FAILURE);
}
return p;
}
int *makeIntArray(int n) {
/* allocates dynamic int array of size/length n */
return safeMalloc(n*sizeof(int));
}
void printIntArray(int length, int *arr) {
printf("[");
if (length > 0) {
printf("%d", arr[0]);
for (int i=1; i<length; i++) {
printf(",%d", arr[i]);
}
}
printf("]\n");
}
int *readSignal(int *len) {
int *x;
char c;
scanf("%d:", len);
x = calloc(*len, sizeof(int));
do c = getchar(); while (c != '[');
if (*len > 0) {
scanf("%d", &x[0]);
for (int i=1; i < *len; i++) scanf(",%d", &x[i]);
}
do c = getchar(); while (c != ']');
return x;
}
void printSignal(int len, int *x) {
printf("%d: [", len);
if (len > 0) {
printf("%d", x[0]);
for (int i=1; i < len; i++) printf(",%d", x[i]);
}
printf("]\n");
}
int main(int argc, char *argv[]) {
int n;
scanf("%d\n", &n);
int len_h_init;
int *h_init;
h_init = readSignal(&len_h_init);
for (int i = 0; i < n; i++){
int len_next;
int *h_next;
int len_temp;
int *temp;
h_next=readSignal(&len_next);
int temp_indent = 0;
len_temp = (len_h_init-1) + len_next;
temp = makeIntArray(len_temp);
for(int i=0; i<len_h_init; i++){
for(int j=0; j<len_next; j++){
temp[temp_indent+j] = temp[temp_indent+j] + h_init[i]*h_next[j];
}
temp_indent = temp_indent + 1;
}
h_init = (int *) realloc(h_init, len_temp);
len_h_init = len_temp;
for(int z = 0; z < len_h_init; z++) {
h_init[z] = temp[z];
}
free(temp);
free(h_next);
}
printSignal(len_h_init, h_init);
return 0;
}
AddressSanitizer showed me that I was getting a heap buffer overflow error. I tried to fix it by freeing h_init before using realloc and that fixed the problem.

Is it possible to dynamically allocate 2-D array in c with using calloc() once?

All the solutions I have seen online has calloc() function used twice, is it possible to do with only using it once?
The below code is not printing the correct array elements
int **ptr;
//To allocate the memory
ptr=(int **)calloc(n,sizeof(int)*m);
printf("\nEnter the elments: ");
//To access the memory
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",ptr[i][j]);
}
}
Since C99 you can use pointers to VLAs (Variable Length Arrays):
int n, m;
scanf("%d %d", &n, &m);
int (*ptr)[m] = malloc(sizeof(int [n][m]));
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d", &ptr[i][j]); // Notice the address of operator (&) for scanf
}
}
free(ptr); // Call free only once
If it's just about minimising the number of calls to memory allocation functions you can created such a jagged array like this:
#include <stdlib.h>
#include <stdio.h>
int ** alloc_jagged_2d_array_of_int(size_t n, size_t m)
{
int ** result = NULL;
size_t t = 0;
t += n * sizeof *result;
t += n*m * sizeof **result;
result = calloc(1, t);
if (NULL != result)
{
for (size_t i = 0; i < n; ++i)
{
result[i] = ((int*) (result + n)) + i*m;
}
}
return result;
}
Use it like this:
#include <stdlib.h>
#include <stdio.h>
int ** alloc_jagged_2d_array_of_int(size_t, size_t);
int main(void)
{
int result = EXIT_SUCCESS;
int ** p = alloc_jagged_2d_array_of_int(2, 3);
if (NULL == p)
{
perror("alloc_jagged_2d_array_of_int() failed");
result = EXIT_FAILURE;
}
else
{
for (size_t i = 0; i < 2; ++i)
{
for (size_t j = 0; j < 3; ++j)
{
p[i][j] = (int) (i*j);
}
}
}
/* Clean up. */
free(p);
return result;
}

Allocating memory for pointer struct which has pointer members

I am trying to read and print using struct pointer which has pointer members. So I am trying to read and print array of double struct pointers.
I tried the folowing but it is giving me error saying "Access violation writing location (somewhere in memory)"
How can I allocate memory dynamically for this?
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
typedef struct template{
char *name;
int *birthdate;
int *phoneNum;
} detailsOf;
void inputValue(detailsOf **person, int maxSize);
int main() {
detailsOf **person;
int maxSize = 0, menu = 0;
printf("Max:");
scanf("%d", &maxSize);
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
if (person == NULL) {
printf("Failed to allocate");
exit(0);
}
for (int i = 0; i < maxSize; i++) {
person[i]->name = (char *)calloc(21, sizeof(char ));
person[i]->birthdate = (int *)calloc(8, sizeof(int ));
person[i]->phoneNum = (int *)calloc(16, sizeof(int ));
}
inputValue(person, maxSize);
for (int i = 0; i < maxSize; i++) {
free(person[i]);
for (int j = 0; j < 21; j++) {
free(person[i]->name[j]);
}
for (int j = 0; j < 15; j++) {
free(person[i]->phoneNum[j]);
}
for (int j = 0; j < 8; j++) {
free(person[i]->birthdate[j]);
}
}
return 0;
}
void inputValue(detailsOf **person, int maxSize) {
for (int i = 0; i < maxSize; i++) {
printf("Name of %d", i + 1);
scanf("%s", person[i]->name);
for (int j = 0; j < 8; j++) {
printf("Birth %d:", i + 1);
scanf("%d", person[i]->birthdate[j]);
}
for (int k = 0; k < 8; k++) {
printf("Phone %d:", i + 1);
scanf("%d", person[i]->phoneNum[k]);
}
}
printf("SUCCESS\n");
}
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
should be
person = malloc(maxSize * sizeof(detailsOf *));
Then, this allocated memory to hold pointers to detailsOf but you never allocate memory for each detailsOf
for(int i=0; i<maxSize; i++)
{
person[i]=malloc(sizeof(detailsOf));
}
Also your freeing of memory should be
for (int i = 0; i < maxSize; i++)
{
free(person[i]->name);
free(person[i]->phoneNum);
free(person[i]->birthdate);
free(person[i]);
}
free(person);
Remember while freeing just match your free calls with malloc calls.
Rule is simple -- a pointer is uninitialized until it has had a valid address assigned to it, or memory has been allocated within which to store things and the starting address for the new block of memory assigned to it.
You allocate maxSize pointers for person, but then fail to allocate a struct for each person[i] before allocating for name, etc..
So you must allocate a struct, e.g. pointer[i] = malloc (sizeof *pointer[i]) before attempting to allocate person[i]->name = calloc(21, sizeof(char ));, ...
Also note, if you allocate based on the size of the derefernced pointer -- you will never get your allocation wrong, (your allocation of person is only correct as the result of happy-accident), instead, e.g.
person = malloc (maxSize * sizeof *person);
...
person[i] = malloc (sizeof *person[i]);
(and note a [] or -> counts as a dereference)
person[i]->name = calloc (21, sizeof *person[i]->name);
There is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
This allocates an array of double pointers to type detailsOf with array size as maxSize.
sizeof(detailsOf**) is the size of an address, it does not give you the size of your user-defined datatype detailsOf.
Also, double pointer means, it is an address location which will store the address of another pointer which points to the memory location of detailsOf
/* if you want to use double pointer then */
detailsOf **dptr; // two dimensional array of detailsOf */
detailsOf *sptr; /* one dimentional array of detailsOf */
/* This allocates the memory for storing 3 detailsOf struct data */
sptr = malloc(3 * sizeof(detailsOf));
dptr = &sptr;
/* Now to access double ptr */
for (int i = 0; i < 3; ++i) {
dptr[0][i].birthdate = malloc(3 * sizeof(int));
}
for (int i = 0; i < 3; ++i) {
dptr[0][i].birthdate[0] = i;
dptr[0][i].birthdate[1] = i + 10;
dptr[0][i].birthdate[2] = i + 1990;
}
for (int i = 0; i < 3; ++i) {
printf("%d\\", dptr[0][i].birthdate[0]);
printf("%d\\", dptr[0][i].birthdate[1]);
printf("%d\n", dptr[0][i].birthdate[2]);
}
/* Not to free the double pointer,
* you have to free the inner pointer first then the outer pointers
* Easy to remember is to free in reverse order of your allocation order
*/
for (int i = 0; i < 3; ++i) {
free(dptr[0][i].birthdate);
free(dptr[0]);
/* free(dptr); this is not needed in this example because
* dptr is pointer to address of a local variable,
* but if it points to address of another array of detailOf*
* then this free is needed
*/
}
In your case, you have just an array of pointer and not an array of double pointers.

struct pointer as return type

I want to print kk[i].data[j] but it is not printing at all.
intarr_save_binary is returning 2. I expect to get 0.
int k = sizeof(kk) / sizeof(kk[0]); gives 0. I'm expecting to get 5.
Did I properly allocate the memory?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int len;
int *data;
}intarr_t;
#define MAX 5
intarr_t* intarr_create(unsigned int len) {
intarr_t* new_intarr = (intarr_t*)malloc(sizeof(intarr_t));
if (!new_intarr) return NULL;
new_intarr->data = (int*)malloc(len * sizeof(int));
new_intarr->len = len;
return new_intarr;
}
int intarr_save_binary(intarr_t* ia, const char* filename) {
if (!ia) return 1;
if (!ia->data) return 2;
FILE* f = fopen(filename, "w");
if (!f) return 3;
if (fwrite(&ia->len, sizeof(ia->len), 1, f) == 1) {
fprintf(f, "%d ", ia->len);
}
else {
return 4;
}
if (fwrite(ia->data, sizeof(ia->data), ia->len, f) == ia->len) {
fclose(f);
return 0;
}
else {
fclose(f);
return 5;
}
}
int main() {
intarr_t *ia = (intarr_t*)malloc(MAX*sizeof(intarr_t));
int i;
int j;
for (j = 0; j < MAX; j++) {
ia[j].len = j + 1;
}
for (j = 0; j < MAX; j++) {
ia[j].data = (int*)malloc(ia[j].len * sizeof(int));
}
for (j = 0; j < MAX; j++) {
for (i = 0; i < ia[j].len; i++) {
ia[j].data = (i + 1) * j;
}
}
char name[20] = "myfile.txt";
int d;
printf("%d \n", intarr_save_binary(ia, name));
intarr_t *kk;
kk = intarr_create(MAX);
int k = sizeof(kk) / sizeof(kk[0]);
printf("%d\n",k);
for (j = 0; j < k; j++) {
for (i = 0; i < kk[j].len; i++) {
printf("%d: %d\n", i, kk[j].data[i]);
}
printf("\n");
}
free(kk);
return 0;
}
intarr_save_binary is returning 2. I expect to get 0.
for (j = 0; j < MAX; j++) {
for (i = 0; i < ia[j].len; i++) {
ia[j].data = (i + 1) * j;
}
}
This zeroes ia[0].data on the very first pass through the double loop. (ia[0].data = (0 + 1) * 0 gives 0).
Thus ia->data is 0, and !ia->data is true, making the function return 2.
int k = sizeof(kk) / sizeof(kk[0]); gives 0. I'm expecting to get 5.
You obviously expect sizeof kk to give the total amount of memory allocated for kk.
And that is what you get, actually -- the total amount of memory allocated for intarr_t *, which is the type of kk at that point. That most likely results in 4 or 8, depending on your architecture. What it is not is whatever len * sizeof(int) resulted in when you called intarr_create(). As #BoPersson commented, if you allocate the memory yourself, you have to remember yourself how much you allocated.
The sizeof kk / sizeof kk[0] "trick" only works if kk actually is an array, i.e. if it has been declared as such within the scope of you using the sizeof operator on it so the compiler can "see" its size.
So, as you have an int and an int * in your struct kk[0], which together are very likely to require more memory than an intarr_t *, the integer division results in 0.
You might also take note that free() is not recursive. With free(kk), you are leaking all the memory you allocated for all the data members. For every malloc(), there needs to be a corresponding free(). (And it does matter even if the program ends right after that one free(), as not all operating systems can / will protect you from this error.)

dynamic memory allocation (C Programming)

I am learning about dynamic memory allocation and having a problem while doing the exercise.
I would like to allocate the memory for p. The following is the codes.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int *p, i;
p = (int *)malloc(7 * sizeof(int));
if (p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
for(i=0; i<6; i++)
{
p++;
*p = i;
printf("%3d",*p);
}
printf("\n");
p = p - 6;
free(p);
p = NULL;
return 0;
}
The running result is:0 1 2 3 4 5
However, when I change the code
p = (int *)malloc(7 * sizeof(int));
to this
p = (int *)malloc(6 * sizeof(int));
the running result would be
0 1 2 3 4 5
Error in `./memo2': free(): invalid next size (fast): 0x0000000001bc5010 ***
Aborted (core dumped)
I think for this code, p only need the memory of the size of 6 integers, could anyone give a explanation?
Another question is that why should p++ be ahead of *p = i? If I make *p = i before p++, the running result would be 0 0 0 0 0 0.
First question - you get an error when you malloc memory for 6 integers because in your for loop you increment the pointer before assigning a value. Therefore you leave the first address you allocated empty. If you assign a value and then increment the pointer this will solve your problem.
Second question - if you perform the printf after incrementing the pointer you won't print the value you just set. You need to assign the value, print it, then increment the pointer.
Here's your code with those changes:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int *p, i;
p = (int *)malloc(6 * sizeof(int));
if (p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
for(i=0; i<6; i++)
{
*p = i;
printf("%3d",*p);
p++;
}
printf("\n");
p = p - 6;
free(p);
p = NULL;
return 0;
}
However, I would recommend you use array indexing syntax. As well as being easier to read, this means that you don't actually change the p meaning that when you free the memory it will be on the correct address. Here's an updated version of your code using array indexing:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int *p, i;
p = (int *)malloc(6 * sizeof(int));
if (p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
for(i=0; i<6; i++)
{
p[i] = i;
printf("%3d",p[i]);
}
printf("\n");
free(p);
p = NULL;
return 0;
}
Your code needs 7 "slots" to store 6 numbers because the very first slot is immediately skipped:
for(i=0; i<6; i++)
{
p++; // <-- Skip to next "slot"
*p = i;
printf("%3d",*p);
}
So the first slot is never used since it's immediately skipped. To fix this, first work with the current pointer, then increment it:
p = malloc(6 * sizeof(int));
if (p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
for(i=0; i<6; i++)
{
*p = i;
printf("%3d",*p);
p++; // <-- Skip to next "slot"
}
Also, the pointer you pass to free must be exactly the same pointer you got from malloc. You can calculate the original value by undoing the additions you did in a loop, but it's easier to store the original value (less chance to screw up):
int *p, *orig_p, i;
orig_p = malloc(6 * sizeof(int));
if (orig_p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
p = orig_p;
...
free(orig_p);
For your subquestion2, find the answer in below
for(i=0; i<6; i++)
{
*p = i;
printf("%3d",*p); //Fix1
p++; //Fix2
}
ie,you should print the value *p before increment the pointer p.
1) When you do like this
for(i=0; i<6; i++)
{
p++; // here before assigning the value you are incrementing address of p(first location is waste)
*p = i;
printf("%3d",*p);
}
So it does not store value in first memory location(this location is wasted). it stores value from second location on wards. so it requires 7 location for 6 numbers.
2) If you make *p = i before p++, like below code-
for(i=0; i<6; i++)
{
*p = i; // you are assigning the value.
p++; // here you are incrementing the value
printf("%3d",*p); // it will print the value at the incremented loaction
}
For example- Consider starting address is 1000. when you do *p = i; i is assigned to 1000, p++; will increment the location to 1004. After incrementing the address you are printing the value. It may give you 0 or garbage values. because printf("%3d",*p); will print the value at 1004. you don't know what value is there. So avoid this types of method.
Try the following code-
p = (int *)malloc(6 * sizeof(int)); // Fix 1
if (p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
for(i=0; i<6; i++)
{
*p = i;
printf("%3d",*p);
p++; // Fix 2
}
printf("\n");
p = p - 6;
free(p);
p = NULL;
Try this.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int *p, i;
p = malloc(7 * sizeof(int)); /* Memory allocated for 7 intergers */
if (p == NULL)
{
printf("Memory Allocation Errors\n");
exit(1);
}
for(i=0; i<=6; i++) /* Assign values */
{
// This is a better way of assignment, easy to understand
// *(p+i) = i OR p[i] = i
p[i] = i;
printf("%3d",p[i]);
}
printf("\n");
// p = p - 6; /* Not required */
free(p); /* Free the pointer */
// p = NULL; /* Not required */
return 0;
}
The output will be:
0 1 2 3 4 5 6
You have p, that's one slot. Then you increment p six times, that's six more slots. So you need seven slots in total.

Resources