I'm new to dynamic memory, I'm trying to learn.
I keep getting in my codes "Process finished with exit code 11".
this is one code:
int main()
{
int *p;
printf("%d",&p);
p = (int)malloc(sizeof(int));
if(p==NULL)
{
printf("failed");
free(p);
exit(1);
}
printf("%d",p);
*p = 4;
printf("%d",*p);
return 0;
}
p = (int)malloc(sizeof(int));
This is not right. malloc returns a pointer (void *) and p is a pointer; there is no need to cast at all, and certainly not to int. If you are very lucky, the cast to int may simply have no effect. If you are unlucky, such as on machines where pointers are 64 bits and int is 32 bits, you'll end up with an incorrect pointer, or some other form of undefined behavior.
A couple other bugs:
You should use the %p format specifier to print pointers, not %d. And you probably want to include spaces or newlines after the values you print, otherwise they'll all run together and be hard to read.
It's good that you check whether malloc succeeded or failed, but if it failed, there is no point in calling free on the null pointer that was returned. free(NULL) is defined as doing nothing.
Here's a corrected version of your program (try on godbolt):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p;
printf("%p\n",&p);
p = malloc(sizeof(int));
if(p==NULL)
{
printf("failed\n");
exit(1);
}
printf("%p\n",p);
*p = 4;
printf("%d\n",*p);
return 0;
}
Related
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.
Can someone tell me, if function fun() is correct?
#include <stdio.h>
#include <stdlib.h>
int *fun(int *, int *, int, int);
int main(void) {
int v1[] = {1,2,3,4,5};
int v2[] = {6,7,8,9,10};
int v1Size = sizeof(v1)/sizeof(v1[0]);
int v2Size = sizeof(v2)/sizeof(v2[0]);
int *v = fun(v1, v2, v1Size, v2Size);
if(v == NULL)
exit(EXIT_FAILURE);
for(size_t i = 0; i < v1Size; ++i)
printf("%d ", v[i]);
}
int *fun(int *v1, int *v2, int v1Size, int v2Size){
if(v1Size!=v2Size)
return NULL;
const int size = v1Size;
int v[size];
for(int i=0; i<size; i++)
v[i]=v1[i]+v2[i];
int *p = v;
return p;
}
For me, it returns the pointer that points memory that will be freed after leaving the fuction body. But valgrind doesn't show any error and it works just fine.
works just fine
Stop !! it's one of the possible outcome of invoking undefined behavior.
As you correctly mentioned, the returned pointer won't be valid (VLAs reside in auto scope (stack), in general, as in gcc) after returning from fun(). Using the return value will lead to UB.
Returning the address of a local variable is not "fine". Once the function exits, v no longer exists, so any pointer to it is no longer valid. Obviously, the storage that v occupied still exists, and as long as nothing else overwrites that storage, your code will appear to function correctly.
Note the emphasis on appear. Your code could just as easily crash, or give garbled output, or otherwise be put into a bad state. It depends on how you use that returned pointer value.
v has auto storage duration, meaning storage for it is allocated at function entry and released at function exit. Valgrind isn't going to say boo about it, because it's not the kind of thing Valgrind checks.
I'm new in StackOverflow. I'm learning C pointer now.
This is my code:
#include <stdio.h>
#include <stdlib.h>
int alloc(int* p){
p = (int*) malloc (sizeof(int));
if(!p){
puts("fail\n");
return 0;
}
*p = 4;
printf("%d\n",*p);
return 1;
}
int main(){
int* pointer;
if(!alloc(pointer)){
return -1;
}else{
printf("%d\n",*pointer);
}
free(pointer);
return 0;
}
I compile with: gcc -o main main.c
error: free(): invalid pointer: 0xb77ac000 ***
what's wrong with my code?
Arguments in C are always passed by value. So, when you call alloc(pointer), you just pass in whatever garbage value pointer contains. Inside the function, the assignment p = (int*)... only modifies the local variable/argument p. Instead, you need to pass the address of pointer into alloc, like so:
int alloc(int **p) {
*p = malloc(sizeof(int)); // side note - notice the lack of a cast
...
**p = 4; // <---- notice the double indirection here
printf("%d\n", **p); // <---- same here
return 1;
}
In main, you would call alloc like this:
if (!(alloc(&pointer))) {
....
Then, your code will work.
Everything in C is pass-by-value. This means that functions always operate on their own local copy of what you pass in to the function. Usually pointers are a good way to mimic a pass-by-reference scheme because a pointer and a copy of that pointer both contain the same memory address. In other words, a pointer and its copy both point to the same space.
In your code the issue is that the function alloc gets its own local copy of the pointer you're passing in. So when you do p = (int*) malloc (sizeof(int)); you're changing the value of p to be a new memory address, but the value of pointer in main remains unchanged.
You can get around this by passing a pointer-to-a-pointer, or by returning the new value of p.
You have two major problems in your code.
First, the alloc function creates a pointer via malloc, but never frees it, nor does it return the pointer to the calling function. This guarantees the memory the pointer addresses can never be freed up via the free command, and you now have memory leaks.
Second, the variable, int* pointer in main, is not being modified as you would think. In C, function arguments are "passed by value". You have two ways to address this problem:
Pass a pointer to the variable you want to modify (in your case, a pointer to a pointer to an int)
Have the function return the pointer to the function that called it.
Here are two implementations of my recommendations:
Approach 1
#include <stdio.h>
#include <stdlib.h>
int alloc(int** p);
int alloc(int** p) {
if (!p) {
printf("Invalid argument\n");
return (-1);
}
if ((*p = (int*)malloc(sizeof(int))) == NULL) {
printf("Memory allocation error\n");
return (-1);
}
**p = 123;
printf("p:%p - *p:%p - **p:%d\n", p, *p, **p);
return 0;
}
int main(){
int* pointer;
if(alloc(&pointer) != 0){
printf("Error calling function\n");
}else{
printf("&pointer:%p- pointer:%p- *pointer:%d\n", &pointer, pointer, *pointer);
}
free(pointer);
return 0;
}
Sample Run for Approach 1
p:0xbfbea07c - *p:0x8656008 - **p:123
&pointer:0xbfbea07cointer - pointer:0x8656008ointer - *pointer:123
Approach 2
#include <stdio.h>
#include <stdlib.h>
int* alloc(void) {
int* p;
if ((p = (int*)malloc(sizeof(int))) == NULL) {
printf("Memory allocation error\n");
return (NULL);
}
*p = 123;
printf("p:%p - *p:%d\n", p, *p);
return p;
}
int main(){
int* pointer = alloc();
if(pointer == NULL) {
printf("Error calling function\n");
}else{
printf("&pointer:%p- pointer:%p- *pointer:%d\n", &pointer, pointer, *pointer);
}
free(pointer);
pointer = NULL;
return 0;
}
Sample Run for Approach 2
p:0x858e008 - *p:123
&pointer:0xbf9bb1ac- pointer:0x858e008- *pointer:123
You are passing the pointer by value into your alloc function. Although that function takes a pointer to an int, that pointer itself cannot be modified by the function. If you make alloc accept **p, set *p = ..., and pass in &pointer from main, it should work.
#include <stdio.h>
#include <stdlib.h>
int alloc(int** p){
*p = (int*) malloc (sizeof(int));
if(!*p){
puts("fail\n");
return 0;
}
**p = 4;
printf("%d\n",**p);
return 1;
}
int main() {
int* pointer;
if(!alloc(&pointer)){
return -1;
} else {
printf("%d\n",*pointer);
}
free(pointer);
return 0;
}
If you want a function to write to a non-array parameter of type T, you must pass a pointer to that parameter.
void func( T *ptr )
{
*ptr = new_value;
}
void foo ( void )
{
T var;
func( &var ); // writes new value to var
}
If T is a pointer type Q *, it would look like
void func( Q **ptr )
{
*ptr = new_pointer_value;
}
void foo ( void )
{
Q *var;
func( &var ); // writes new pointer value to var
}
If Q is a pointer type R *, you would get
void func( R ***ptr )
{
*ptr = new_pointer_to_pointer_value;
}
void foo ( void )
{
R **var;
func( &var ); // writes new pointer to pointer value to var
}
The pattern is the same in all three cases; you're passing the address of the variable var, so the formal parameter ptr has to have one more level of indirection than the actual parameter var.
One sylistic nit: instead of writing
p = (int *) malloc( sizeof (int) );
use
p = malloc( sizeof *p );
instead.
In C (as of the 1989 standard), you don't need to cast the result of malloc; void pointers can be assigned to other pointer types and vice versa without needing a cast (this is not true in C++, but if you're writing C++, you should be using the new operator instead of malloc anyway). Also, under the 1989 version of the language, using the cast would mask a bug if you forgot to include stdlib.h or otherwise didn't have a declaration for malloc in scope. That hasn't been a problem since the 1999 version, though, so now it's more a matter of readability than anything else.
The type of the expression *p is int, so the result of sizeof *p is the same as the result of sizeof (int). This way, if you ever change the type of p, you don't have to modify the malloc call.
To allocate an array of values, you'd use something like
T *p = malloc( sizeof *p * NUM_ELEMENTS );
or, if you want everything to be zeroed out initially, use
T *p = calloc( sizeof *p, NUM_ELEMENTS );
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 );
}
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