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...
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?
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
#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..
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.