4

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
  • 1
    You can't return arrays from functions in C, but this code does not even attempt that; here ptr[0] is returned, which is a pointer to a local variable. The lifetime of the local variable has ended after the function has returned.... Commented Nov 1, 2017 at 15:12
  • Can this problem be solved using static integer pointer variable and returning ptr instead of *ptr? Commented Nov 1, 2017 at 15:29
  • What is your expected output? Commented Nov 1, 2017 at 15:30
  • @SrihariRaoM -- probably, but that is not ideal; better to either pass an array from the caller into the function, or dynamically allocate within the function. You could also wrap ptr[] in a struct and return that, since structs can be returned from functions. Commented Nov 1, 2017 at 15:33
  • Possible duplicate of Returning an array using C Commented Nov 1, 2017 at 15:52

3 Answers 3

3

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

Sign up to request clarification or add additional context in comments.

Comments

2
#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 Comments

Your program is logically wrong. result[20] array is a local variable of function c2i() and you are storing the address of its elements in ptr[i] and returning ptr and in main(), reading the content of a local variable address in it. You are lucky that It's working somehow but this is undefined behavior.
@H.S. yes result array should also be created using malloc . edited
Still, there are issues in your program. In this statement - ptr = (int *)malloc(10*sizeof(int *)) ; you are typecasting malloc return to (int *) but ptr is of type int **. Moreover, you should not typecast the malloc result.
@srikanth_16 I copy pasted your code and tried to execute the same but I am not getting the output that you have got.
here is the link to ideone. seems it is working fine. ideone.com/YHGgmX . let me now what is the problem you are having ??
|
2

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.