Returning an array of pointers from a function

I am trying to print the integer value of each character in a given string using a function. When I pass a string to this function, it converts each character in the given string to an integer and then saves it to a result array. I have also created an array of pointers which will hold the address of each character's corresponding integer. But when I return this array of pointers, I am not able to print all integer values correctly.

#include <stdio.h>
int *c2i(char *str);
int main(){ char s[20]; int *p, i; printf("Enter your string:\n"); scanf("%s", s); p=c2i(s); for(i=0; i<4; i++){ printf("\n%d\t%d\n", *p, p); p++; } return 0;
}
int *c2i(char *str){ int i=0, result[20], *ptr[20]; while(*(str+i)!='\0'){ result[i]=*(str+i) & 0xff; ptr[i]=&result[i]; i++; } printf("%d %d %d %d %d %d %d %d", *ptr[0], *ptr[1], *ptr[2], *ptr[3], ptr[0], ptr[1], ptr[2], ptr[3]); return *ptr;
}

I have included many printf statements just for debugging purposes. The output of the program when I try to run the code above is:

Enter your string:

abcd

97 98 99 100 6356588 6356592 6356596 6356600

97 6356588

1999382056 6356592

20 6356596

1 6356600

I am only getting the first value correctly when I print it in the main() function. When I increment the pointer and try to print the next values, I am getting garbage results. I can see that the address is the same but the values have been corrupted. What am I doing wrong here?

5

3 Answers

You can't return the stack-allocated array since once the function call finishes, it is no longer marked in use. Instead, you should malloc the array, for example int *ptr = malloc(sizeof(int)*20);. Also remember to free the array when done with it (it's good practice). See these posts for details

Returning an array using C

returning a local variable from function in C

#include <stdio.h>
int** c2i(char *str) { int i=0, *result, **ptr; result = (int *)malloc(20*sizeof(int)) ; ptr = (int **)malloc(10*sizeof(int *)) ; while(*(str+i)!='\0'){ result[i]=*(str+i) & 0xff; ptr[i]=&result[i]; i++; } printf("%d %d %d %d %p %p %p %p", *ptr[0], *ptr[1], *ptr[2], *ptr[3], ptr[0], ptr[1], ptr[2], ptr[3]); return ptr;
}
int main(){ char s[20]; int **p, i; printf("Enter your string:\n"); scanf("%s", s); p=c2i(s); for(i=0; i<4; i++){ printf("\n%d\t%p\n", **p, *p); p++; } return 0;
}

double-pointer might solve your issue, look at your modified code..this gives you the desired result.here i'm attaching the screen shot of execution..enter image description here

6

How about this

#include <stdio.h>
#include <string.h>
#define MAXLEN 20
void c2i(char *str, int *out, int len);
int main(){ char s[MAXLEN]; int out[MAXLEN]; int *p, i; printf("Enter your string:\n"); /* fgets safer that scanf, protects buffer overrun */ fgets(s, sizeof(s), stdin); /* fgets gives you the newline char though, so remove it */ if(s[strlen(s)-1] == '\n') { s[strlen(s)-1] = '\0'; } c2i(s,out,strlen(s)); for(i=0; i<strlen(s); i++){ printf("%d\n", out[i]); } return 0;
}
void c2i(char *str, int *out, int len){ int i=0; for(i=0; i<len; i++) { out[i]=*(str+i) & 0xff; }
}

Passing the out buffer to c2i means you don't need to malloc/free a buffer, but this is probably just a matter of taste.

Using fgets means rather than scanf means you're protected from buffer overruns and your strings can have spaces in them too.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like