Pointer returning garbage value - c

I don't know what I'm doing wrong I'm stuck on this for the past two hours. Any help would be highly appreciated.
My code is the following:-
#include <stdio.h>
int* findLargest(int* arr,int size){
return &arr[size-1];
}
int main(){
int size=3;
int arr[3]={3,4,5};
int* largest=&arr[size-1];
int* largest2=malloc(100);
largest2=findLargest(*arr,size);
printf("%d",largest);
printf("%d",*largest2);
}
I get a garbage value when I execute.

Only pass arr to findLargest, this is already a pointer
largest2=findLargest(arr,size);
printf contents of largest, not the pointer itself
printf("%d\n", *largest);
Also, I'm not sure why you have the line:
int* largest2=malloc(100);
The malloc'd pointer is immediately lost in the next line when you assign to largest2 again.
I would also consider assigning size like so:
int size = sizeof(arr)/sizeof(arr[0]);
This is safer if you change the contents of arr in the future.
With all these changes main looks like:
int main()
{
int arr[3]={3,4,5};
size_t size = sizeof(arr)/sizeof(arr[0]);
int* largest=&arr[size-1];
int* largest2=findLargest(arr,size); // Only pass array to findLargest, this is already a pointer
printf("%d\n", *largest); // printf contents of largest, not the pointer
printf("%d\n", *largest2);
}

The problem here is this line
printf("%d",largest);
Where you're not de-referencing the pointer. Nor is there a space or new line after the value causing more confusion.

you can't edit address of pointer, you've to edit value of pointer
like this:
int * v = malloc(sizeof(int)); //WRONG
int n=54;
v=&n;
int * v = malloc(sizeof(int)); //CORRECT
int n=54;
*v=n;

Well, the problem was simple. Just in case someone runs into this confusion this can help.
The correct code is:
#include <stdio.h>
int* findLargest(int* arr,int size){
return &arr[size-1];
}
int main(){
int size=3;
int arr[3]={3,4,5};
int* largest=&arr[size-1];
int* largest2=malloc(100);
largest2=findLargest(arr,size);//Not findLargest(*arr,size)
printf("%d",*largest2);
}

Related

How to fill an array of structs in a function [duplicate]

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.

Returning pointers back to itself

My coding assignments came with it's header file, meaning we need to use the same data types, and not vary anything.
There is a lot of pointers, (mainly a lot of void *). Meaning things are confusing, more than difficult.
we have to do a separate function, just to increment the value referenced by a pointer. But given the nature of program, I don't want to constantly make new pointers.
The code is as follows:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int a;
a=atoi(str);
return &a;
}
void *intal_increment(void *intal)
{
int *a= (int *)intal;//new pointer;
++*a;
//value referenced has been incremented;
*(int *)intal=*a;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char *dummy;
gets(dummy);
x=(int *)intal_create(dummy);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*(int *)x);
printf("address stored is %p\n",(int *)x);
}
I wanted x to be the parameter called, and also for it to store the return value. The printf address is merely for my understanding.
The segmentation faults never end, and from my understanding, I'm just returning a pointer and asking a pointer to stop the return pointer
By incorporating all the comments. Mainly allocating memory to dummy before passing it gets() function and allocating memory in heap for the return pointer of intal_create.These two fixes solve the issue. Have a look at the following code for reference.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void* intal_create(const char* );
void* intal_increment(void* );
void *intal_create(const char* str)
{
int *a = (int *)malloc(sizeof(int));
*a = atoi(str);
return a;
}
void *intal_increment(void *intal)
{
//Here i am not allocating
int *a = (int *)intal;//new pointer;
(*a)++;
return intal;
}
int main()
{
int * x;// void * return a pointer, need a pointert to int to pick it up
char dummy[20] = {0};
fgets(dummy,5,stdin);
x = (int *)intal_create(dummy);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void*)x);
x=(int *)intal_increment(x);
printf("integer return is %d\n",*x);
printf("address stored is %p\n",(void *)x);
//Make sure you deallocate the memory allocated in the intal_create function.
free(x);
}

how to pass array of pointer of pointers to a function?

I know how to modify an array of pointers in main, but don't know how to do it when my function need to modify it.
The code between ** is how I do it in main without using a function. I know how to print the array of pointer of pointer out. My question is, suppose I want to move these lines ** into function(), what do I need to modify?
code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void function(char *array[], int size);
void function_print(char *array[], int size);
int main()
{
char *array[] = {0};
char word[20];
**scanf("%s", word);
int len = strlen(word) + 1;
array[size] = (char *)malloc(sizeof(len));
strlcpy(array[size], word, sizeof(array[size]));**
function(array, 0);
return 0;
}
void function(char *array[], int size)
{
}
void function_print(char *array[], int size)
{
for(int x = 0; x < size; x ++)
{
printf("%s", *array);
(array)++;
}
}
~
~
I made some edit and realized your function will do the same. So go on, and read the EDIT if you don't know how it works.
Besides I think there's something wrong in your main(). First, array[size] = (char *)malloc(sizeof(len)); tends to report an error because no size is defined here. Second, if by size you mean the number of elements in array, then array[size] would cause an overflow. Third, the argument of malloc should be sizeof(char)*len, not sizeof(len), since the latter equals sizeof(int).
Change your function to
void function(char **, int);
And call it by
function(array, 0);
EDIT
I think by "modify it" you mean to change the pointers stored in the array. Since every element is a char*, a char** will do the job.
When you pass array as an argument, actually you're passing the address of the first element. Then in the function you receive it with a char** parray. Since you have also passed the size, you can use it as a char* parray[], and the address of every element is exactly the same with array in main(). Thus, any modification you do with parray will change array. Is that what you want?
You are doing no mistake in calling the function and passing the array of char pointers. This is a right way. Your program did not compile for me, so made some small changes. It works.
#include<stdio.h>
#include<string.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
void function(char *array[], int size);
int main()
{
char *array[] = {0};
char word[20];
scanf("%s", word);
int len = strlen(word) + 1;
array[0] = (char *)malloc(sizeof(len)); //that how I do it in main without using a function.
strcpy(array[0], word);
function(array, 0);
return 0;
}
void function(char *array[], int size)
{
char * temp = new char[strlen(array[0])+1];
strcpy(temp, array[0]);
printf(temp, 's');
}
Writing this :
void function(char *array[], int size)
and this:
void function(char **array, int size)
are same in this context.
If you define a function like this then its not necessary to declare it like the same , you can declare it like :
void function(char **, int );
declaration only describes the return type and arguments' type of a function.Now, some other recommendations:
Do not use scanf like this :
scanf("%s", word);// you need to specify field width in case of strings otherwise it will overwrite buffer in case of large strings therefore, do it like this :
scanf("%19s",word);
size is not defined in your main, instead I would rather prefer to do this way :
size_t len = sizeof(word) + 1;// yes, try to use size_t when returning number of bytes
*array = (char*)malloc(sizeof len);// casting malloc is not recommended though.
strncpy(*array, word,len);
Try doing :
void function(char *array, int size)();
And instead of:
function(array,0);
because array itself it is a memroy address.

C - passing allocated pointer and using realloc in separate function

I need to find all the prime factors of a number. I have written this code, but when I try to reallocate the pointer array in calculatePrimes function using realloc, gcc gives error that i have not allocated the pointer before using realloc. I know I can pass the double pointer and use malloc inside the calculatePrimes function or, use a single pointer and return the value.
Code:
#include "stdio.h"
#include <math.h>
#include <stdlib.h>
void calculatePrimes(int max, int** array){
int size=1, i;
*array[0]=2;
for(i=0; i<max; i++){
if(isPrime(i)){
*array = (int *)realloc(**array, (++size)*sizeof(int));
*array[size-1]=i;
}
}
}
int isPrime(int value){
int i=2, root = sqrt(value);
for(;i<root;i++){
if(value%i==0) return 0;
}
return 1;
}
void main(int argc, char*argv[]){
int input = atoi(argv[1]), numPrimes;
int *primes=(int *)malloc(sizeof(int));
calculatePrimes(input, &primes);
numPrimes=sizeof(primes)/sizeof(int);
printf("%d\n", numPrimes);
free(primes);
}
Incorrect usage of realloc(). The correct is below:
*array = realloc(*array, (++size)*sizeof(int));
When you pass **array to realloc() you pass the value of the first element of the array that is int instead of int*.
Note that I've also removed the cast. In C, it's not needed and can hide certain problems you don't want hidden. Specifically, it can give you the wrong function signature for malloc/realloc which, if your int and void* type aren't compatible, can lead to corrupted pointers.

Passing around int pointers in structs

I am struggling really hard to understand this behavior so maybe someone can shed some light on the situation.
I simply can't figure out why I can't return a pointer to a struct from a method and expect to be able to still re-use it afterwards.
As you can see the generateSmallMatrix() method creates an int[] array and sets it inside the ysmf struct that I then return to main. Main then takes the ysmf* and calls printArray (again). And on the third try the array cannot be retrieved any more..
It's driving me crazy..
I have checked with my Eclipse debugger that on all calls the location of matrix->A is identical (0x7fffffffe180 - so for all I know about C pointers any form of accessing that int should return the correct value - be it *(ax++) or ax[i]) .. but neither do..
Very frustrating to say the least, so here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct sparseMatrix
{
int* A;
} ysmf;
void printArray(int* ax, int length) {
int i = 0;
for (i = 0; i < length; i++) {
printf("%i,", ax[i]);
}
printf("\n");
}
ysmf* generateSmallMatrix()
{
ysmf *matrix = malloc(sizeof(ysmf));
int a[] = {1,2,3,9,1,4};
printArray(a, 6); // returns 1,2,3,9,1,4,
matrix->A = a;
printArray(matrix->A, 6); //returns 1,2,3,9,1,4,
//printArray(matrix->A, 6);
return matrix;
}
int main(void) {
ysmf* matrix = generateSmallMatrix();
printArray(matrix->A, 6); //returns 1,6,-7856,32767,1,4,
return EXIT_SUCCESS;
}
You can see the problem occuring where I have inserted the comments.
I know this is probably something totally basic I shouldn't have missed..
Because a is a local array, whose lifetime ends when the generateSmallMatrix() function ends. Accessing it after that results in undefined behaviour.
This line
ysmf *matrix = malloc(sizeof(ysmf));
Allocates only enough space for your ysmf struct, which in this case, is just an int pointer. So you then go and point that at 'a'.
matrix->A = a;
The problem is that a is on the stack. So it is now pointing at this memory address but when you exit the function that memory is no longer reserved for the array.
If you instead malloced memory for 'a' and pointed your struct at that, then you would be OK.
Try this...
ysmf* generateSmallMatrix()
{
ysmf *matrix = malloc(sizeof(ysmf));
int a[] = {1,2,3,9,1,4};
printArray(a, 6);
matrix->A = malloc(sizeof(int) * 6);
memcpy(matrix->A, a, sizeof(int) * 6);
printArray(matrix->A, 6);
return matrix;
}
Now outside of the generateSmallMatrix function you should be able to print the correct values. However, be sure to free what was malloc'd.
int main(void) {
ysmf* matrix = generateSmallMatrix();
printArray(matrix->A, 6);
free(matrix->A);
free(matrix);
return EXIT_SUCCESS;
}
Hope this helps.

Resources