This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 3 years ago.
How can I change a heap allocated global pointer from within a function? Here is what I am working with, (call to modify_p seg faults and I can't see much in the debugger):
#include <stdio.h>
#include <stdlib.h>
int *p;
void set_p(int *p, int sz) {
p = malloc(sz * sizeof(int));
}
void modify_p(int *p) {
p[0] = 2;
}
int main(int argc, char *argv[])
{
set_p(p, 3);
modify_p(p);
//printf("%d\n", p[0]);
// should print 2
return 0;
}
Thanks
The issue is that you pass a copy of p to set_p. So the original p is never modified and never points to valid memory, and the copy is lost at the end of set_p, leaking the memory. Instead, pass a pointer to p (so a pointer to a pointer), like this:
void set_p(int **p, int sz) {
*p = malloc(sz * sizeof(int));
}
And call the function like this:
set_p(&p, 3);
Then you get the expected result.
One way would be to do this:
#include <stdio.h>
#include <stdlib.h>
int *p;
void set_p(int sz) {
p = malloc(sz * sizeof(int));
}
void modify_p() {
p[0] = 2;
}
int main(int argc, char *argv[])
{
set_p(3);
modify_p();
printf("%d\n", p[0]);
// should print 2
return 0;
}
As p is declared outside of any function, you can write directly to it. When you do set_p(p, 3);, the set_p function will have it's local copy of the variable.
If you want to change what a pointer points to, you have to pass the address of the pointer (as shown by Blaze).
Related
Since the pointer p is passed-by-pointer shouldn't the output in main be "Hi there"?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char *);
int main() {
char *p = "Hello";
func(p);
puts(p); //Hello <-- Shouldn't this be Hi there
return 0;
}
void func(char *p) {
p = (char *)malloc(100);
strcpy(p, "Hi there");
puts(p); //Hi there
}
Isn't the pointer passed to function func not the same as pointer p inside the function func?
C is not pass-by-reference, so when you write to p in func, you're writing to func's copy of p, not main's copy.
p is passed as a pointer to func, but you're trying to modify the pointer itself. You'd need to pass a pointer to a pointer to modify p.
To fix this issue, pass a pointer to p to func, like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char **);
int main(void) // int main(void) is more up-to-date
{
char *p = "Hello";
func(&p); // pass a pointer to p
puts(p); // Hi there
free(p); // free memory that you've allocated
return 0;
}
void func(char **pp) // char ** for pointer-to-pointer
{
*pp = malloc(100); // don't cast the result of malloc()
strcpy(*pp, "Hi there"); // formatting, use *pp instead of p
puts(*pp); // Hi there
}
This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 4 years ago.
I'm trying to create an array of a structure in an external function "add", and print it's fields, but when I get back to the main function "arr" it is still NULL.
I'm confused because I've been creating arrays in external functions many times and it worked.. probably this time the dynamic memory allocation is messing the things up. Can I please get an advice on this matter?
Thanks!
typedef struct {
char* id;
char gender;
char *name;
}Member;
void add(Member arr[], int size);
void print(Member arr[], int *size);
int main()
{
char temp[100];
int size=0;
Member *arr = NULL;
Member *data = (Member*)malloc(sizeof(Member));
//scan fields
gets(temp);
data->id = (char*)malloc((strlen(temp) + 1) * sizeof(char));
strcpy(data->id, temp);
gets(temp);
data->gender = temp;
gets(temp);
data->name = (char*)malloc((strlen(temp) + 1) * sizeof(char));
strcpy(data->name, temp);
add(data, &arr, &size);
print(arr, &size);
return 0;
}
void add(Member *data, Member arr[], int *size)
{
arr = (Member*)realloc(arr, (*size + 1) * sizeof(Member));
arr[*size] = *data;
}
void print(Member arr[], int *size)
{
for (int i = 0;i < *size;i++)
{
puts(arr->id);
puts(arr->gender);
puts(arr->name);
}
}
Imagine code like this:
#include <stdio.h>
void f(int i){
i++;
}
int main(){
int i = 3;
f(3);
printf("%d\n", i);
}
We all know that f() incremented its local copy of i, not the variable that was passed into f() to initially set that value. With that having been said, let's take another look at your add():
void add(Member *data, Member arr[], int *size)
{
arr = (Member*)realloc(arr, (*size + 1) * sizeof(Member));
arr[*size] = *data;
}
When arr is passed into the function, it contains a memory address of the current arr, which starts as NULL. But just like when we change the local value of i in f() above, setting arr to a new value within add() only changes the local value; it does not change main()'s arr.
We also know that if we pass a function an address of data we want it to change, the function can then change the data at that address and the data at that address will reflect the change in the calling function:
#include <stdio.h>
void f(int * i){
*i = *i + 1;
}
int main(){
int i = 3;
f(&i);
printf("%d\n", i);
}
The same logic applies ( though it gets more confusing) when you want to change a pointer's value; send that pointer's address! Let's start with a very simple case:
#include <stdio.h>
#include <stdlib.h>
void f(int** i){
*i = (int*)malloc(sizeof(int));
**i = 99;
}
int main(){
int *i = NULL;
f(&i);
printf("%d\n", *i);
}
Here we create a pointer to an int in main, and initialize it to NULL. Then we send the address of that pointer (that is, the address we stored the NULL) to f(), which (like in your program) allocates some memory and puts the address of the newly allocated pointer _at the address of main's i. Now, the data stored at &i has changed, and dereferencing i from main() will dereference the newly allocated address.
In your code, just as in mine, you'll have to change the way you're passing arr to add() as well as how you interact with it - an exercise you'll get the most out of thinking through yourself. But in short, something like this should get you started:
pass add arr's address, not the address it stores.
Store new address of reallocated memory back to the same address, that is, &arr
make sure to update add() to dereference the pointer to a pointer twice to set the member at the address stored at the address &arr.
This question already has answers here:
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 8 years ago.
I want to make a function in C that would dynamically allocate memory for a pointer in parameter of the function.
#include <stdio.h>
#include <stdlib.h>
int allocate(char * arr, int size){
int code = -1;
arr = malloc(size);
if(arr != NULL) code = size;
return code;
}
void main(){
char * array;
if(allocate(array,4) != -1){
printf("allocated!\n");
if(array == NULL) printf("Oops it actually didn't allocate!\n");
}
}
When I execute the program; it will only display "allocated!" and "Oops it actually didn't allocate!". That means the memory allocation did happen (because the return code of the function is not -1. But then when I check if array is equal to NULL; it actually is!
This is a programming problem that I've had and sadly in some cases I can't use a workaround like this char * allocate(char * arr, int size); and assigning the return value to char * array.
You lack a level of indirection, you need char**.
Excuse the bad formatting, I write from my phone.
Char* array, array is bound to a memory slot (that will contain a value that points to another memory slot that would be interpreted as a char).
So you copy that value to the function and modify that value locally in allocate, but the modification never reaches the outside scope.
#include <stdio.h>
#include <stdlib.h>
int allocate(char ** arr, int size){
int code = -1;
*arr = malloc(size);
if(*arr != NULL) code = size;
return code;
}
void main(){
char * array;
if(allocate(&array,4) != -1){
printf("allocated!\n");
if(array == NULL) printf("Oops it actually didn't allocate!\n");
}
}
Not done C in something like 10 years but it should be OK.
You can allocate memory inside your function and return the address as shown below
There are also changes like instead of void main it should be int main()
#include <stdio.h>
#include <stdlib.h>
char *allocate( int size){
char *arr;
arr = malloc(size);
return arr;
}
int main(){
char * array;
if((array = allocate(4)) != NULL){
printf("allocated!\n");
}
return 0;
}
Arguments to functions in C are passed by value. This means following function has no sense:
void f(int x) {
x = 1;
}
int y = 0;
f(y);
// y is still 0
When f is invoked, y is copied to x. Any change to x changes that copy and won't affect y. To work around this, you need to either use return value or pass a pointer to y:
void f(int* x) {
*x = 1;
}
int y = 0;
f(&y);
// y is now 1
Here x is still a copy (of a pointer) but it points to y. Changes to x wont be visible outside that function. But changing *x modifies y.
The same rules apply to pointer arguments. You just need one more * for arguments you want to modify:
int allocate(char** arr, int size) {
*arr = malloc(size);
}
char *ptr;
allocate(&ptr);
Also note that checking array for NULL isn't sufficient here, because a locally defined variable could contain garbage value (thus, not being NULL). You have to assign NULL to it before the allocation:
char *array = NULL;
Okay so I am trying to pass a char pointer to another function. I can do this with an array of a char but cannot do with a char pointer. Problem is I don't know the size of it so I cannot declare anything about the size within the main() function.
#include <stdio.h>
void ptrch ( char * point) {
point = "asd";
}
int main() {
char * point;
ptrch(point);
printf("%s\n", point);
return 0;
}
This does not work however, these two works:
1)
#include <stdio.h>
int main() {
char * point;
point = "asd";
printf("%s\n", point);
return 0;
}
2)
#include <stdio.h>
#include <string.h>
void ptrch ( char * point) {
strcpy(point, "asd");
}
int main() {
char point[10];
ptrch(point);
printf("%s\n", point);
return 0;
}
So I am trying to understand the reason and a possible solution for my problem
This should work since pointer to the char pointer is passed. Therefore any changes to the pointer will be seen outside thereafter.
void ptrch ( char ** point) {
*point = "asd";
}
int main() {
char * point;
ptrch(&point);
printf("%s\n", point);
return 0;
}
void ptrch ( char * point) {
point = "asd";
}
Your pointer is passed by value, and this code copies, then overwrites the copy. So the original pointer is untouched.
P.S. Point to be noted that when you do point = "blah" you are creating a string literal, and any attempt to modify is Undefined behaviour, so it should really be const char *
To Fix - pass a pointer to a pointer as #Hassan TM does, or return the pointer as below.
const char *ptrch () {
return "asd";
}
...
const char* point = ptrch();
Here:
int main() {
char * point;
ptrch(point);
You're passing point by value. Then, ptrch sets its own local copy of point to point to "asd", leaving the point in main untouched.
A solution would be to pass a pointer to main's point:
void ptrch(char **pp) { *pp = "asd"; return; }
If you change the value of the pointer in a function, it will remain changed only in that one function call.
Don't mess your head with pointers and try:
void func(int i){
i=5;
}
int main(){
int i=0;
func(i);
printf("%d\n",i);
return 0;
}
The same with your pointer. You do not change the address it points to.
If you assign to a variable passed by value, the variable outside the function will remain unchanged.
You could pass it by a pointer (to pointer) and change it by dereferrencing it and it's the same with an int - in this case, it doesn't matter if the type is int or char * .
first declare funtion......like this
#include<stdio.h>
void function_call(char s)
next write main code.....
void main()
{
void (*pnt)(char); // pointer function declaration....
pnt=&function_call; // assign address of function
(*pnt)('b'); // call funtion....
}
Why doesn't this print 5?
void writeValue(int* value) {
value = malloc(sizeof(int));
*value = 5;
}
int main(int argc, char * argv) {
int* value = NULL;
writeValue(value);
printf("value = %d\n", *value); // error trying to access 0x00000000
}
and how can I modify this so it would work while still using a pointer as an argument to writeValue?
Your pointer (int *value) is a value. If you want to keep the above behavior, you need a pointer to a pointer.
void writeValue(int** value) {
*value = malloc(sizeof(int));
**value = 5;
}
int main(int argc, char * argv) {
int *value = NULL;
writeValue(&value); // Address of the pointer value, creates int**
printf("value = %d\n", *value); // prints 5
}
There are 2 bugs, from what I see:
1) If you want to change the value of your pointer you need to pass a pointer to the pointer to your function int **value.
2) If you want to print the value of the pointer in your main, you need to defreference it, *value.
call malloc before calling writevalue, not inside it (thus you'll get the added benefit to be able to free it).
Your program doesn't print 5, but also has a memory leak by losing address of allocated bloc.
The reason as also explained by others is that the parameter int * value is a copy of int * valuein main. You can think of it as a local variable of the function. You can only access to the place it is pointing to. When you modify value in the function the other value in main is not changed.
void writeValue(int* value) {
*value = 5;
}
int main(int argc, char * argv) {
int* value = NULL;
value = malloc(sizeof(int));
writeValue(value);
printf("value = %d\n", *value);
free(value);
}