1

I want to fill an array of char, one by one, so I am using the above code for testing, and the final output of "str" will always be the first char entered instead of all char, whats wrong ?

void gime_char(char c)
{
    static *str;
    static i;

    if(i == 0)
        str = malloc(sizeof(*str) * 10);
    if(c == 'X')
    {
        printf("full str:%s\n", str);
    }
    printf("c == %c\n", c);
    str[i] = c;
    printf("d == %d\n", i);
    i++;
}

int main()
{
    char c;

    while(c != 'X')
    {
        c = getchar();
        gime_char(c);
    }
}
1
  • are you sure "static i;" is initialized to 0? Commented Nov 15, 2013 at 12:59

4 Answers 4

2

The type of static *str is static int *str, but a string consists of chars. So now your string does not end up being stored with the characters adjacent to one another as you would expect, because each element of str has the size of int (probably 4 bytes), not that of char.

This part of the code should be fixed by specifying the type as static char *str. Once you fix that, there will be another problem when printing str without terminating it with a NUL character ('\0').

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

3 Comments

do you know why it still print the first charact ? since he interpret it at int *str
@Saxtheowl You mean why it prints the first char even though the type is int? It so happens that on your platform the lowest byte of the int is stored first in memory, and the other bytes are zero since you only assigned a single byte, so the first two bytes happen to be your first char and zero, which makes up a valid single-character string in C. (Note that this depends on byte order.)
(I also recommend increasing the warning levels of your compiler; it should have warned when passing str to printf with the format %s.)
2

You're missing a type in the definition of i, and the type in the definition of str is incomplete: you say “pointer” (with the * character) but you don't say to what. For historical reasons, if you omit a type, the compiler assumes you meant int; this is deprecated, and good compilers warn about this.

Since you effectively wrote int *str, the memory layout looks something like this after entering hello (this is machine-dependent, but this is a pretty typical case):

+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
| 'h' |   0 |   0 |   0 | 'e' |   0 |   0 |   0 | 'l' |   0 | ...
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----
 ^                       ^                       ^
 |                       |                       |
str                    str+1                   str+2

Each small cell is one byte (which corresponds to one character). Four cells make up one int. The line

str[i] = c;

writes one int into str. For example, when c is 'h', which has the numerical value 104, the number 104 is written into the int object str[0], which is represented as the four-byte sequence {104, 0, 0, 0}. This happens again for the next character, which is written in the next int-sized slot in the array, meaning 4 bytes further.

In the line

printf("full str:%s\n", str);

you print str as a string. In a string, the first zero byte marks the end of the string. So you see the string "h".

Your machine is little-endian. Exercise: what would you see on a big-endian machine?

The fix is to declare the types properly.

You should also initialize your variables. static variables are initialized to 0 anyway, but it's clearer if you do it explicitly. The variable c is not static, so it starts out containing whichever value was there before in memory; this could happen to be 'X', so you must initialize it explicitly.

Additionally, you need to make sure that the string is terminated by a zero byte before printing it. The static keyword ensures that the str variable is initialized to a null pointer, but the space that the pointer points to is allocated by malloc and contains whatever was there before.

void            gime_char(char c)
{
  static        char *str;         /* <<<< */
  static        int i;             /* <<<< */

  if(i == 0)
    str = malloc(sizeof(*str) * 10);
  if(c == 'X')
    {
      str[i] = 0;                 /* <<<< */
      printf("full str:%s\n", str);
    }
  printf("c == %c\n", c);
  str[i] = c;
  printf("d == %d\n", i);
  i++;
}

int             main()
{
  char          c = 0;             /* <<<< */

  while(c != 'X')
    {
      c = getchar();
      gime_char(c);
    }
  return 0;                        /* <<<< */
}

Comments

1

Advices :

  • Check that malloc didn't return an error
  • i is not initialize
  • Type of *str is wrong (static char *str)
  • Before using %s you have to add a '\0' at the end of your string.

2 Comments

i dont need to be initialized since is a static, no ?
@Saxtheowl ...but it is better to read for everyone else (knowing against seeing)
0

I would say your problem comes from fact that you declare static *str;. You declare it with out specifying the type! Compilers pass with, with a warning that this implies an int. So basically you end up with a static pointer to int. Which is not meant to store ANSI strings.

Later you allocate space for the buffer (I suppose) with str = malloc(sizeof(*str) * 10);. This is also wrong, because you allocate space for 10 pointers to str.

You want to work with characters.

static char *str;
if(i == 0)
  str = malloc(sizeof(char) * 10);

Also you should initialize the string to zeros as it is almost certain you will get some garbage there and ANSI string is expected to be NULL terminated. Preferably i too but compilers initialize variables on stack.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.