Are character arrays supposed to behave differently from integer arrays?

Well, the code is C. I hope nobody minds that considering it's a forum for C++. In any case, it's just standard C, so I think the same should be applicable in C++.
So... The code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
 * 
 */
int twister(void);

int main(void) {
    int *p;
    p = twister();
    unsigned int i;
    for (i=0;i<10;i++) {
        printf("%i\n",*p); *p++;
    }
    return (EXIT_SUCCESS);
}

int twister(void) {
    srand(time(0));
    static int x[10] = {0};
    unsigned int i;
    for(i=0;i<10;i++) {
        x[i] = rand()%('z'-'a')+'a';
    }
    return x;
}


Ok... It runs good. Gives me 10 random integers between 97 and 122... Before someone points out abundant instances of bad programming practices, please know that I know they exist (abundantly) and gcc warns me about them every time I compile, however it's not my biggest concern right now.
The problem is: I want twister() to return char instead. However, when I do that, a memory access exception is thrown by my OS, says: Segmentation fault...
I tried to go pro and cranked gdb up... It appears that char *p cannot acquire return value properly even though the return value has been declared static.

The things which bugs me the most is that it works flawlessly (apparently) with integers! So why problem with characters?

I have frequently noticed character arrays (or C type strings, as I think they are referred to as) being mentioned separately from normal arrays in tutorials, books and articles. Do they behave differently?

And lastly, I am not even sure if that is the right question to ask. I have always had problems with pointers, I have a crystal clear concept tonight and in the morning I wouldn't even be able to justify why I need pointers. There is a string chance I am doing something terribly stupidly wrong. Could anyone point out please?

(And try not to be too blunt, you know, I have feelings... Alright, I don't. :p)
The return type of twister should be a pointer. Your code would not have compiled in C++ because of the stronger type safety. The reason it works in C is probably because sizeof(int) == sizeof(int*) so the implicit casts works just fine. When you change to char it fails to work because sizeof(char) != sizeof(char*).
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
 * 
 */
char* twister(void);

int main(void) {
    char* p;
    p = twister();
    unsigned int i;
    for (i=0;i<10;i++) {
        printf("%c\n",p[i]);
    }
    return (EXIT_SUCCESS);
}

char* twister(void) {
    srand(time(0));
    static char x[10] = {0};
    unsigned int i;
    for(i=0;i<10;i++) {
        x[i] = rand()%('z'-'a')+'a';
    }
    return x;
}

and gcc warns me about them every time I compile, however it's not my biggest concern right now.
*sigh*, that is precisely the problem.
If you want to return a pointer, then you should return a pointer. char* twister(void);
Hi, there's an invalid assignment to p, because it's a pointer to integer (int*), while te twister function return an integer value (int). However, for your question, 'char' type and 'int' type are different, because the 'int' type is 4 byte long in memory, the 'char' type is for the standard 1 byte long.
Then, the return value of the 'twisted' function isn't valid because you just return an array in a function that return an 'int' value.
for this reason, you should use dynamic allocation with pointers, try to modify your code to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
 * 
 */
#define RANGE ('z'-'a')    //the number of characters in the alfabet
#define INIT 'a'  //the initial character

char* twister(int n);  // the 'n' is for the dynamic allocation of the char array

int main(void) {
    char *p;
    int n=10;  //the dimension of the array
    p = twister(n);
    for (int i=0;i<n;++i) {
        printf("%c\n",p[i]);
    }
    delete [] p;    // remove the array allocated from memory
    return (EXIT_SUCCESS);
}

char* twister(int n) {
    srand(time(0));
    char* x=new char[n];
    for(int i=0;i<n;++i) {
        x[i] = (char)((rand()%RANGE)+INIT);
    }
    return x;
}

The return type of twister should be a pointer. Your code would not have compiled in C++ because of the stronger type safety. The reason it works in C is probably because sizeof(int) == sizeof(int*) so the implicit casts works just fine. When you change to char it fails to work because sizeof(char) != sizeof(char*).

Thank you very very much Peter87... That was precisely the answer I was looking for. You explained the reason why gdb gave me a QWORD value for int *p and BYTE value for char *p.

Thank you Moschops, for the code. That was what I thought I should have done after reading the post by Peter87.

*sigh*, that is precisely the problem.

Ah! I see that now, ne555. Haha! People who built gcc have a higher IQ than me, and I should listen to it no matter how irrelevant the warning looks to me. Cheers! :)

@Vins3Xtreme: Very nice of you to sum up. However I couldn't help noticing that in the modified code, you have used preproc define for RANGE and INIT. Any particular reason? I can't see how that makes a difference.
EDIT: I might be wrong, but did you re-write the code in C++? I don't think new exists in C. I do get the concept though. I shall try to make it work with malloc.

Thank you all. I shall mark this thread solved now. Cheers.
Last edited on
Topic archived. No new replies allowed.