Reputation: 158
I am writing a simple function in C that should build a char array from string "abc" – so it should build {'a','b','c'} – and return a pointer to that array. Here is my code for this function:
char * makeArr()
{
static char arr[3];
sprintf(arr, "%s\n", "abc");
return arr;
}
Problems occur when I call this method in main:
int main(int argc, char *argv[])
{
char *arr[3];
arr = makeArr();
return 0;
}
The compiler is complaining about casting / conflicting types. I've been playing with pointers, casting and dereferencing for quite a while now, but can't seem to get it to work. Please let me know where my logic is wrong.
Upvotes: 0
Views: 2150
Reputation:
Hmm ... there are several errors in this code. Let's start with the most obvious your compiler complains about:
char *arr[3];
This line declares arr
to be an array of three pointers to char
. What you return from your function is a single pointer to a char
-> doesn't match.
Next:
static char arr[3];
sprintf(arr, "%s\n", "abc")
Here you reserve 3 char
s. the sprintf()
will write 5 char
s. %s
is replaced by the 3 characters in your string literal "abc"
. You add a newline character and then a 0
is added as the marker for the end of the "string". Makes 5. This btw is undefined behavior. You write past the end of your array. Code like this can be compiled, but there's no guarantee at all about what will happen at runtime.
Doing a cut here. You should read about arrays and pointers in C. If the text you're reading claims they are the same ... stop right there and find a better text. They aren't.
I'll try to explain this here briefly, so it's suitable for the Q&A style.
An array in C indeed is a contiguous space of several values. char arr[3]
means a variable that holds 3 char
s.
On the other hand, a char *
is just a pointer pointing to a char
-- this could be the first element of an array.
In C, you can't pass arrays as function parameters, and you can't return arrays from a function. Trying to do so leads to an implicit conversion: What is actually passed is a pointer to the first element of that array.
I think the last bit of information missing is what a string literal in C is: it's an array (anonymous, e.g., it doesn't have a name) containing all the characters in the double quotes plus a 0
appended. The 0
marks the end of a "string" in C.
In an expression, a string literal evaluates to a pointer to the first element.
So, something like this:
char *foo = "bar";
will lead to foo
pointing to the b
of the array. It's like writing
static const char no_name_0[] = { 'b', 'a', 'r', 0 };
char *foo = &(no_name_0[0]);
Upvotes: 2
Reputation: 2513
You couldn't assign the result of makeArr to arr. I guess that's your casting error. Oversimplifying, arr points to the place on the stack where the array of 10 characters is allocated. So, I'd pass in arr to makeArr as a char*. So, you'd end up with something like this:
#include <stdio.h>
char * makeArr(char *arr)
{
sprintf(arr, "%s\n", "abc");
return arr;
}
int main(int argc, char *argv[])
{
char arr[10];
makeArr(arr);
printf("%s\n", arr);
return 0;
}
Upvotes: 0
Reputation: 83
Pass the array as an argument and modify it in the called function, would be easier. If you're statically creating the array and there's no need to allocate memory, don't, just pass around your pointers to the functions to be modified by reference
void makeArr(char arr[]){
sprintf(arr, "%s\n", "abc");
}
Simply pass the existing declared array to the makeArr function...
int main(int argc, char *argv[]) {
char arr[10];
makeArr(arr);
return 0;
}
Upvotes: 0
Reputation: 75062
Firstly, char arr[3];
is too snall to store "abc\n"
. It must have at least 5 elements including terminating null-character.
Then, char *arr[3];
is a 3-element array of char*
.
You should assign makeArr()
's return value (it has char*
type) to arr[0]
or another element, or you should change the type of arr
in main
function to char*
, which is the same type as makeArr()
's return value.
Moreover, this makeArr()
doesn't make any array and returns (a pointer to) the existing array. Yoy should use malloc()
to "make an array".
UPDATE:
Assigning a value of char*
to the array char arr[10];
seems invalid in C.
You should use strcpy()
or strncpy()
(safer than strcpy()
) to copy the string stored in the array between arrays.
Upvotes: 1
Reputation: 17678
Among other things, you confused:
char arr[3]; // array of 3 chars.
and,
char *arr[3]; // array of 3 pointers to char.
In main(), you should only write char *arr;
Upvotes: 2