Segmentation Fault when attempting to print value in C - c

The following C code returns a "segmentation fault" error. I do not understand why it does not return the value 20. What is my error?
#include <stdio.h>
int main()
{
int* n;
*n = 20;
printf("%i\n",*n);
return 0;
}

You haven't allocated memory to n, so
*n = 20;
attempts to write unspecified memory.
Try
#include <stdlib.h>
int *n = malloc(sizeof *n);
/* use n */
free(n);

You haven't allocated space for your int, you've only declared a pointer to an int.
The pointer is uninitialized, and so writing to that unknown space in memory is undefined behavior and causes problems. This typically causes a segfault.
You can allocate a slot for an integer using malloc:
n = malloc(sizeof(int));
And use a corresponding call to free to free up the memory later:
free(n);
But allocating a single slot for an integer is pretty unusual, typically you would allocate the int on the stack:
int n;
n = 20;

You are trying to write 20 in garbage value. You must allocate space for it by using one of *alloc() functions or creating an int on stack and getting the andress of it(as Richard J. Ross III mentioned on comments).
dynamic allocation:
int n*;
n = malloc(sizeof(int)); /* allocate space for an int */
if(n != NULL) {
/* do something.. */
free(n); /* free 'n' */
} else {
/*No space available. */
}
or on the stack:
int int_on_stack;
int *n = &int_on_stack;
*n = 20;
printf("%i\n", *n); // 20

Related

Trying to free reallocated memory gives free(): invalid pointer

I can't figure out why I am getting the error free(): invalid pointer when running this code. I thought p is going to point to a block of memory set aside for the structures, so I am trying to free pointers beginning from the p e.g. p+1, but this is no good. What am I missing here?
#include <stdio.h>
#include <stdlib.h>
struct s {
int x;
};
int main()
{
struct s *p = NULL;
for (int i = 0; i < 3; i++) {
if ((p = realloc(p, (i+1) * sizeof(struct s))) != NULL) {
struct s x = {.x=i*10};
*(p+i) = x;
} else exit(EXIT_FAILURE);
}
for (int i=0;i<3;i++) {printf("%d ", (p+i)->x);}
//free(p);
free(p+1);
//free(p+2);
return 0;
}
Before the loop you declared the pointer p
struct s *p = NULL;
So after the loop it will store the address of the last reallocated memory.
To free the allocated memory you need just to write
free( p );
The expression p + 1 points to the second element of the dynamically allocated array that was not allocated dynamically. It is the whole array that was allocated dynamically.

Initialize array of pointers to NULL with realloc without iteration

Is it possible to automatically initialize to NULL the pointers inside an array reallocated with realloc without iterate over it? I would like to do something like calloc but i need te resize an already existent block of memory.
For example:
#DEFINE N 50
typedef int *pointerToInt;
typedef pointerToInt *pointerToPointer;
int main(){
pointerToInt p;
pointerToPointer pp;
pp = malloc(sizeof(p)*N);
//Now i want to resize and initialize my resized vector
pp = realloc(pp, sizeof(p)*(N+10));
}
In first approximation I could change the mallocto calloc, but when I use realloc there's nothing that guarantees me initialized pointers.
Is it necessary to iterate over the whole array and set each single pointer to NULL? Or there's a better way using only callocand realloc?
The short answer is: No, there is no standard function to reallocate a block of memory and initialize its newly allocated portion to all bits zero.
The solution is either:
to not require initialization by keeping track of the valid portion of the array. You obviously must have a way to do this, otherwise how would you decide to reallocate the object.
to initialize the newly allocated portion explicitly.
There are several problems in your code:
#DEFINE N = 50 is incorrect, it should just be #define N 50
hiding pointers behind typedefs is bad: it makes the code obscure and error prone. To do it twice is evil.
you did not include <stdlib.h>
you do not test for malloc failure
you do not initialize the array allocated by malloc() either.
Here is a modified version:
#include <stdlib.h>
#define N 50
int main(void) {
int i;
int **pp, **pp1;
pp = malloc(sizeof(*pp) * N);
if (pp) {
for (i = 0; i < N; i++) {
pp[i] = NULL;
}
//Now I want to resize and initialize my resized vector
pp1 = realloc(pp, sizeof(*pp) * (N + 10));
if (pp1) {
pp = pp1;
for (i = N; i < N + 10; i++) {
pp[i] = NULL;
}
}
free(pp);
}
return 0;
}
Note that you could write a utility function for your purpose:
#include <stdlib.h>
#include <string.h>
void *realloc_zero(void *p, size_t size, size_t new_count, size_t count, int *err) {
void *newp;
if (p == NULL)
count = 0;
newp = realloc(p, size * new_count);
if (newp == NULL) {
*err = 1;
return p;
} else {
if (new_count > count) {
memset((unsigned char*)newp + size * count, 0, size * (new_count - count));
}
*err = 0;
return newp;
}
}
#define N 50
int main(void) {
int err;
int **pp;
pp = calloc(sizeof(*pp), N);
...
//Now I want to resize and initialize my resized vector
pp = realloc_zero(pp, sizeof(*pp), N + 10, N, &err);
if (err) {
// could not resize
free(pp);
return 1;
}
...
free(pp);
return 0;
}
Note however that both calloc and realloc_zero initialize the block to all bits zero, which is not guaranteed by the C Standard to be a proper representation of NULL, although most current architectures do represent the null pointer this way.
No, there is no automatic way. You must iterate and set each uninitialized pointer.

HEAP CORRUPTION DETECTED memory leak in C

I got and error which says
Debug assertation failed and heat corruption detected
like everything is working good in my program but I get that error. Where is the memory leak here? I have to free that memory in the main because my functions need to return pointers.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *dynamic_reader(unsigned int n) {
/*making new array and checking if allocation succeeded*/
int *mem;
mem = malloc(n * sizeof(int));
if (!mem) {
printf("Memory allocation failed\n");
exit(-1);
}
/*letting the user to input the values for the array*/
int i = 0;
while (i < n) {
scanf("\n%d", &mem[i]);
i++;
}
/*printing the array just to make sure everything is good*/
for (int j = 0; j < n; j++) {
printf("%d ", mem[j]);
}
return mem;
}
int *insert_into_array(int *arr, unsigned int num, int newval) {
/*making new bigger array*/
int *newarr = realloc(arr, (num + 1) * sizeof(int));
/*adding the integer to this new array */
newarr[num] = newval;
printf("\n");
/*printing to make sure everything is correct*/
for (int j = 0; j < num + 1; j++) {
printf("%d ", newarr[j]);
}
return newarr;
}
int main(void) {
/*In dynamic_reader function I need to make an array which size is given as a parameter*/
/*In this case I choosed 3*/
int *arr = dynamic_reader(3);
int num = 3;
/*In insert_into_array function I need to add one integer to this array I made in dynamic_reader*/
/*The parameters are the array, the number of elements in the array already done and the integer I want to add*/
int *c = insert_into_array(arr, num, 9);
/*I free the memory here because I need to return the pointers of these arrays in the function so it cant be done there*/
free(arr);
free(c);
}
You are double freeing your memory. Check the documentation for realloc. Realloc will either 1) expand the passed buffer or 2) will allocate a new buffer, copy the data, and free the original buffer. When you do:
free(arr);
free(c);
You are double freeing a value that was either once already freed by realloc or already freed by the first free(arr)
Additionally, you should check if realloc fails (returns NULL) and if so, handle the case appropriately.
First you malloc an array, which you return to your main function as arr. Then in another function, you realloc where arr is an argument to the realloc, but some other pointer stores the results. Depending on what happened in realloc, you've either got arr and newarr pointing to the same location, or newarr pointing to a valid location and arr pointing to an invalid location that has been freed. Either way, freeing both of them at the end is a problem.
No need to free(arr), that is taken care of when you realloc() it. The pointer returned by realloc() will either point to memory which includes the original memory, or free the old memory after copying its content to a new, larger chunk of memory.

freeing a structure array allocated with double pointer

Here is basically what I'm trying to do:
free memory that was allocated in a different scope using double pointers.
The following code is incomplete but fully describes what I'm trying to perform.
so here is my function to read the buffer (C pseudo code)
char *read_buffer(char *buf, myStruct **arr, int nbElm)
{
buf = malloc(...);
...//many things done (use of the read(),close()... functions
...//but not referencing any of the buffer to my structure
...
*arr = (myStruct *) = malloc(sizeof(myStruct) * nbElm);
return (buf);
}
Here is the kind of function I use between my memory allocation and my freeing attempt:
void using_struct(myStruct *ar, int nbElm)
{
int i;
i = 0;
while (i < nbElm)
{
// Here I use my struct with no problems
// I can even retrieve its datas in the main scope
// not memory is allocated to it.
}
}
my main function :
int main(void)
{
char *buf;
myStruct *arStruct;
int nbElm = 4;
buf = read_buffer(buf, &arStruct, nbElm);
using_struct(arStruct, nbElm);
free(buf);
buf = NULL;
free(arStruct);
while(1)
{;}
return (1);
}
The only problem is either I place my while loop before or after my free function, I can't see any memory change using top
on my terminal.
Is this normal?
Thanks in advance,
You always must have exactly same number of calls to free as a calls to malloc.
myStruct **arr;
*arr = malloc(sizeof(myStruct) * nbElm);
This means you need single call to free first nbElm structs:
free(arr);

understand passing parameters by reference with dynamic allocation

I'm trying understand how to pass a parameter by reference in C language.
So I wrote this code to test the behavior of parameters passing:
#include <stdio.h>
#include <stdlib.h>
void alocar(int* n){
n = (int*) malloc( sizeof(int));
if( n == NULL )
exit(-1);
*n = 12;
printf("%d.\n", *n);
}
int main()
{
int* n;
alocar( n );
printf("%d.\n", *n);
return 0;
}
Here is printed:
12.
0.
Example 2:
#include <stdio.h>
#include <stdlib.h>
void alocar(int* n){
*n = 12;
printf("%d.\n", *n);
}
int main()
{
int* n;
n = (int*) malloc(sizeof(int));
if( n == NULL )
exit(-1);
alocar( n );
printf("%d.\n", *n);
return 0;
}
It printed:
12.
12.
What's the difference of this two programs?
C is pass-by-value, it doesn't provide pass-by-reference.
In your case, the pointer (not what it points to) is copied to the function paramer (the pointer is passed by value - the value of a pointer is an address)
void alocar(int* n){
//n is just a local variable here.
n = (int*) malloc( sizeof(int));
//assigning to n just assigns to the local
//n variable, the caller is not affected.
You'd want something like:
int *alocar(void){
int *n = malloc( sizeof(int));
if( n == NULL )
exit(-1);
*n = 12;
printf("%d.\n", *n);
return n;
}
int main()
{
int* n;
n = alocar();
printf("%d.\n", *n);
return 0;
}
Or:
void alocar(int** n){
*n = malloc( sizeof(int));
if( *n == NULL )
exit(-1);
**n = 12;
printf("%d.\n", **n);
}
int main()
{
int* n;
alocar( &n );
printf("%d.\n", *n);
return 0;
}
Actually not really much a difference, except the first one is broken. :) (Well, both are, but the first is broken more).
Let me explain what happens in the second case:
variable n of type pointer-to-int is allocated on the stack
a new variable of type int is allocated to the stack, it's address is stored in variable n
function alocar is called, being passed the copy of variable n, which is the copy of the address of our variable of type int
the function sets the int variable being pointed by n to 12
the function prints the value of the variable being pointed by n (12)
the function returns
The first case:
variable n of type pointer-to-int is allocated on the stack
the function alocar is called with a copy of the variable n (which is still uninitialized - contains an unknown value)
a new variable of type int is created in memory and the local copy of variable n in function alocar is set to point to that new variable
the variable (pointed by the function's local copy of n) is set to 12 and printed
the function returns, again in the main() function:
since the original n variable in main is still uninitialized, it points to a random place in memory. So the value in random place in memory is printed (which is likely to crash your program).
Also, both programs are broken because they don't free the memory allocated by malloc().
You want to modify the value of n in main, not what n points to, so you need to pass a pointer to it. Since the type of n in main is int *, the parameter to alocar needs to be of type int **:
void alocar(int **n)
{
*n = malloc(sizeof **n); // note no cast, operand of sizeof
if (!*n)
exit(-1);
**n = 12;
printf("%d\n", **n);
}
int main(void)
{
int *n;
alocar(&n);
printf("%d\n", *n); // we've already tested against n being NULL in alocar
free(n); // always clean up after yourself
return 0;
}
The answer posted by nos is correct.
Also note that the first of the two posted programs will actually crash on many systems, when the printf line in main() tries to dereference main's pointer n, which was never set:
printf("%d.\n", *n);
See, what's happened in first program.
Before call to alocar we have just variable n in main, pointing to some undefined place:
main()::n [ X--]--->(?)
(there's value in square brackets, which is undefined, marked as X). Then we call alocar, and we have another variable in alocar's scope, which have a copy of origianl var.
main()::n [ X--]--->(?)
alocar()::n [ X--]-----^
Now, allocate some memory:
main()::n [ X--]--->(?)
alocar()::n [ *--]--->[ Y ]
Assign value to allocated var:
main()::n [ X--]--->(?)
alocar()::n [ *--]--->[ 12 ]
Return. alocar()::n is removed as it live only while alocar() is executed.
main()::n [ X--]--->(?)
[ 12 ]
main()::n is still pointing to some undefined place... (Which possibly stores value 0) And no one points to allocated place.

Resources