I apologize by advance if my question seems absolutely trivial, but I don't understand why if I run
int main(){
int *count = 0;
printf("%d",*count);
}
I have no input (using Xcode) and an error:
Thread 1 : EXC_BAD_ACCESS(code=1, address = 0x0)
Could someone explain to me what this is?
What happens is dereferencing a null pointer, which is undefined behavior: your count is a pointer, which means that it needs to point to a valid location before you can read from it:
int main(){
int *count = malloc(sizeof(int)); // Give your pointer a valid location
*count = 123; // This is valid now
printf("%d", *count); // prints 123
free(count); // Don't forget to free allocated memory
}
You have declared count as a pointer to an integer value not as an integer value and you have initialized the pointer to be NULL (memory address 0).
You would want to do the following...
int main()
{
int buffer = 0;
int* count = &buffer;
printf( "var %d = %d\n", buffer, *count );
}
Related
I'm trying to learn the memory allocation in C using malloc and increasing the size of allocated array using realloc inside a function. I came across this. when I use single variable the code is working well. But when I allocate memory for second variable, it gives me weird output.
Code is below:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
# define N 3
void padd(int *a){
int sizes = 10*sizeof(int);
a = (void *)realloc(a,sizes);
a[0] = 10;
printf("inside func= %d \n",a[0]);
}
int main()
{
int *d;
int *pA;
int size = N*sizeof(int);
pA = (void *)malloc(size);
//d = (int *)malloc(size);
padd(pA);
printf("outside func= %d",pA[0]);
}
it gives me output:
inside func= 10
outside func= 10
but if I uncomment the //d = (int *)malloc(size); line, It gives me
inside func= 10
outside func= -1368048824
as output.
What might be wrong here?
If realloc can’t extend a buffer in place, it will allocate a new buffer, copy the contents of the old buffer to it, free the old buffer, and return the address of the new buffer (or NULL if it cannot satisfy the request); thus, the value of a can change in padd. However, that change is only applied to the formal parameter a - the actual parameter pA is not affected.
Based on the behavior, it looks like that if you allocate d, it’s allocated immediately after pA such that pA can’t be extended in place, so realloc is creating a new buffer and deallocating the old one, and the old buffer is overwritten before the printf statement in main.
You’ll want to write padd such that any changes to a are reflected in pA - either return the (potentially new) value of a or pass a pointer to pA:
void padd( int **a )
{
size_t sizes = 10 * sizeof (int); // see note 1
int *tmp = realloc( *a, sizes ); // see note 2
if ( tmp )
{
*a = tmp;
(*a)[0] = 10;
printf( "Inside func, (*a)[0] = %d\n", (*a)[0] );
}
else
{
printf ( "Inside func, realloc failed!\n" );
}
}
and you’d call it as
padd( &pA );
Note 1: sizeof has type size_t, not int.
Note 2: Since realloc can potentially return NULL, always assign the result to a temporary value and check it before assigning back to the original variable, otherwise you run the risk of losing access to memory you’ve already allocated. Also, the cast to void * is unnecessary and confusing since you’re assigning the result to an int * variable. Unless you’re compiling this code as C++ or under an ancient K&R C compiler, just leave the cast off completely - otherwise, your cast has to match the type of the thing you’re assigning to, which in this case is int *.
You should either get the new pointer back from padd:
int * padd(int * a){
int sizes = 10*sizeof(int);
a = (void *)realloc(a,sizes);
a[0] = 10;
printf("inside func= %d \n",a[0]);
return a;
}
//...
int main()
{
//...
pA = padd(pA);
//...
}
Or pass a pointer to the pointer:
void padd(int **pA){
int *a = *pA;
int sizes = 10*sizeof(int);
a = (void *)realloc(a,sizes);
a[0] = 10;
printf("inside func= %d \n",a[0]);
*pA = a;
}
//...
int main()
{
//...
padd(&pA);
//...
}
The both your programs have undefined behavior.
The function parameter a
void padd(int *a)
is a local variable of the function that is initialized by the value of the pointer pA used as a function argument in the function call
padd(pA);
You can imagine the function definition and its call the following way
padd(pA);
//...
void padd( /* int *a */ ){
int *a = pA;
int sizes = 10*sizeof(int);
a = (void *)realloc(a,sizes);
a[0] = 10;
printf("inside func= %d \n",a[0]);
}
So as it is seen changing the local variable a within the function padd does not influence on the value stored in the pointer pA because the function deals with a copy of the value of the pointer pA.
To change the original pointer pA within the function you need to pass it to the function by reference.
In C passing by reference means passing an object indirectly through a pointer to it. Thus dereferencing the pointer you will get a direct access to the object.
The function should be declared and defined the following way
int padd( int **a ){
int sizes = 10*sizeof(int);
int *tmp = realloc( *a, size );
int success = tmp != NULL;
if ( success )
{
*a = tmp;
( *a )[0] = 10;
// or **a = 10;
printf("inside func= %d \n", ( *a )[0] );
}
return success;
}
And the function can be called like
if ( padd( &pA () ) printf("outside func= %d",pA[0]);
Pay attention to that to call realloc you should use an intermediate variable because in general the function can return a null pointer. So reassigning the original pointer with a null pointer results in the original value of the pointer will be lost.
Also you should free all the dynamically allocated memory when it is not needed any more
free( pA );
I have a method called printNums, where I would like to print integers from 1 - 10. For my assignment, I'm supposed to malloc an int pointer, set it, pass in to my function as a void* point and inside the function, cast it, deference it and print that integer out before each iteration of the counter.
However, I keep getting a segmentation fault after *((int*)ptr) and I'm not too sure why. Any help would be appreciated.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void* printNums(void *ptr);
int main(int argc, char **argv)
{
int *ptr = (int*)malloc(sizeof(int));
ptr = 0;
printNums(ptr);
return 0;
}
void* printNums(void *ptr){
int i = 0;
for (i = 0; i <= 10; i++){
*((int*)ptr) = i;
printf("%d\n", *((int*)ptr));
}
}
You're assigning ptr pointer to zero.
change ptr = 0; to *ptr = 0;.
You are resetting the address to zero:
ptr = 0;
Which means you will definitely (in most environments and operating systems) get a segmentation fault if you try to access it.
I think you wanted to set the value pointed by ptr to 0 before you can use, so by mistake you made ptr = 0
to make all the values pointed by ptr to be 0 you need to use memset
memset(ptr,0,sizeof(int));
However, I keep getting a segmentation fault after *((int*)ptr) and
I'm not too sure why.
You can try to find out yourself. Programming requires some debugging skills - forums are not the replacement.
void* printNums(void *ptr){
int i = 0;
for (i = 0; i <= 10; i++){
printf("%p\n", ptr);
//*((int*)ptr) = i;
//printf("%d\n", *((int*)ptr));
}
return ptr;
}
https://godbolt.org/z/EYhGKn
and the output
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
And the answer is obvious: you dereference NULL pointer.
Now you can try to find out why you pass the NULL pointer to the function. As the program is 12 lines long it will not take too much time to discover the line:
ptr = 0;
Which assigns integer zero to the pointer. So the pointer is now NULL.
I have a function to update an unsigned char* and cannot find where my bug is. I'm not sure if I need to allocate memory, or if I am pointing to the wrong memory space somewhere. I tried to follow a similar structure as posted here, but have not had success with an unsigned char.
My code so far:
#include <stdio.h>
void changeArray(unsigned char **arr)
{
unsigned char ptr[3] = {100, 101, 102};
*arr = ptr;
printf("%d\n", **(arr+0)); // This prints out the correct value of 100
}
int main(int argc, const char* argv[])
{
int i = 0;
unsigned char *blah;
unsigned char ptr2[3] = {103, 104, 105};
blah = ptr2;
printf("Blah is: \n");
for (i = 0; i < 3; i++) {
printf("%d,",*(blah+i)); //This prints out 103,104,105
}
changeArray(&blah);
printf("Blah is now: \n");
for (i = 0; i < 3; i++) {
printf("%d,", *(blah +i)); //This prints out 0,0,0
}
return 0;
}
Any help in determining how to properly access the values set in the changeArray() function would be greatly appreciated.
With this *arr = ptr; you are storing a pointer to a variable with automatic storage duration. The behaviour undefined.
You can dynamically allocate and return a pointer that way:
void changeArray(unsigned char **arr)
{
unsigned char ptr[3] = {100, 101, 102};
unsigned char *p = malloc(sizeof ptr);
memcpy(p, ptr, sizeof ptr);
*arr = p;
printf("%d\n", **(arr+0)); // This prints out the correct value of 100
}
You should also do error checking if malloc failed and remember to free the allocated memory after use in main.
The problem here is, ptr is local to changeArray() function. So once the function finishes execution, there is no existance of ptr. Hence, once you assign ptr to *arr
*arr = ptr;
and changeArray() execution gets over, accessing blah in main() now will invoke undefined behaviour.
FWIW, you don't need to pass the address of blah, you don't need a pointer-to-pointer at all. blah is already a pointer, which you can pass to changeArray() to alter the contents of the memory area it points to. You can do something like
void changeArray(unsigned char *arr)
{
for (int i = 0; i < 3; i ++)
arr[i] = 100+i;
}
and call it like
changeArray(blah);
So I wrote this code but it gives me the same answer everytime. I am increasing the memory allocated to the pointer in steps of 4 and then print the value.
#include <stdio.h>
int main(void) {
int n=0;
char *name = "hello";
scanf("%d",&n);
for(int i =0; i<n;i++){
name += sizeof(int);
printf("%d \n", (sizeof(&name)));
}
return 0;
}
can someone help me? I don't know whats wrong here. I don't need a different code, I just want to understand what's wrong with this.
Try the following, error checking was left out for clarity:
#include <stdio.h>
int main(void)
{
int n=0;
char *name = null;
scanf("%d",&n);
for(int i=0; i<n;i++)
{
char *buffer = null;
//allocate/reallocate the buffer. increases by 4 bytes every iteration
buffer = (char*) realloc(name, (i+1)*4);
name = buffer;
printf("%d \n", (sizeof(&name)));
}
//release the memory used by the buffer
free(name);
return 0;
}
Here are some explanations of what is happening.
#include <stdio.h>
int main(void) {
int n=0;
// this does not actually allocate any memory. It sets the POINTER name to point (like an arrow) to a read-only block that contains "hello"
char *name = "hello";
// string literals generally come in fixed read-only memory
scanf("%d",&n);
for(int i =0; i<n;i++){
// this causes the pointer memory address to be incremented by sizeof(int) (typically 4)
// after the first increment if it will point to a string "o" (incremented by 4 characters)
// after the second increment it will point to some undefined memory behind "hello" in your virtual address space and will have undefined behaviour when accessed
name += sizeof(int);
// sizeof(&name) will give you the size of a char **. Pointer to a character pointer.
// Wich is the same size as all pointers.
// = sizeof(void *) = 8 for 64-bit systems, 4 for 32-bit systems
printf("%d \n", (sizeof(&name)));
}
return 0;
}
This is the way to do it:
#include <stdio.h>
int main(void) {
int n=0;
// allocate 10 bytes of memory and assign that memory address to name
char *name = malloc(10);
// the size of that memory needs to be kept in a separate variable
size_t name_length = 10;
// copy the desired contents into that memory
memcpy(name, "hello", sizeof("hello"));
scanf("%d",&n);
for(int i =0; i<n;i++){
// reallocate the memory into something with sizeof(int) more bytes
void * tmp = realloc(name, name_length += sizeof(int));
// this can fail
if (tmp) {
name = tmp;
} else {
perror("realloc");
exit(-1);
}
printf("%d \n", name_length);
}
return 0;
}
You have not allocated any memory for the pointer at all in the code you provide. You will have to deal with dynamic memory if you want to change the size of the allocated chunk. You will have to initially use malloc and then use realloc to allocate more memory on each step.
Let's step through your code one by one:
char *name = "hello";
this create an array of chars 'h','e','l','l','o',0 and assignes the memory address of the first character to name
for(int i =0; i<n;i++){
name += sizeof(int);
printf("%d \n", (sizeof(&name)));
}
here you add to the name pointer the size of int, which increments this pointer by 4 each pass.
Since this is a char pointer, the pointer is incremented by 4 bytes - since sizeof(int) == 4
You cannot increase the size of your hello char array, since it is not a dynamic array.
If you wish to be able to resize the string, you should malloc and copy the chars to the bigger array.
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.