Hi,
I am trying to reassign an array of char to a string literal by
calling a function.
Arrays cannot be assigned to. They are non-modifiable lvalues.
Individual elements of an array can be assigned to, though.
In the function I use pointer-to-pointer since I want to reassign the
"string array pointer" to the string literal.
It doesn't work that way. Types don't magically change to what you want
them to be. If you pass type A to a function, the function will not
receive type B under any circumstances. In your code, you lied about the
argument type the function expected and passed it a type that didn't
match the type the function thought it was receiving.
But the second printf seems to give me garbage.
That's a perfectly valid result, under the circumstances.
Any advise on what I am doing wrong?
You are invoking undefined behavior.
First, here are the diagnostics issued by my compiler (gcc using a
custom set of warning options):
"C:\cygwin\bin\gcc.exe" -W -Wall -Wcast-align -Wwrite-strings
-Wno-sign-compare -Wno-unused-parameter -Wpointer-arith -ansi
-pedantic-errors -ggdb -c fun.c
fun.c:5: error: initialization discards qualifiers from pointer target type
fun.c: In function `main':
fun.c:13: warning: implicit declaration of function `call'
fun.c:10: warning: unused variable `x'
Terminated with exit code 1
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
You don't seem to be using anything from said:
static char *b = "This is a test";
This is the source of the first error. String literals are
non-modifiable, but a dangerous and archaic language feature allows a
string literal to be assigned to a (non-const) char pointer. Doing so is
almost always a mistake, because it allows you to attempt to modify the
string literal through that pointer, and the compiler is generally not
able or required to warn you about it. I use -Wwrite-strings in order to
receive a diagnostic when this dangerous feature is used.
int main( int argc, char **argv ) {
char a[10] = "abc";
int x;
'x' is not used.
printf( "1st : a = %s*\n", a );
call(&a);
'call' is not declared. Calling an undeclared function is a bad idea,
and no longer valid under the latest standard. You should always have a
declaration (specifically, a prototype) in scope before calling any
function. Because you did not, 'call' was implicitly declared, and that
implicit declaration does not match the function's real signature.
When I added a prototype for 'call', the following diagnostic was added:
fun.c:15: error: passing arg 1 of `call' from incompatible pointer type
The expression &a has type char (*)[10] (pointer to array[10] of char).
This is a completely different type from char ** (pointer to pointer to
char).
printf( "2nd : a = %s*\n", a );
Wouldn't hurt to add:
return 0;
}
int call( char **input ) {
*input = b;
What did you expect this to do? If you passed it the address of a char
pointer, it would make that pointer point to the string literal, but it
would still be dangerous because it makes a non-const pointer point to a
non-modifiable object (the string literal). If you fixed b's declaration:
static const char * const b = "This is a test";
(Second const added for good measure - it's not needed to avoid the
problem in question, but seems to be what was intended anyway.)
Now the compiler will diagnose this assignment because it loses a
'const' qualifier.
What do you really want to do? You can always make a char pointer point
to a different string if you want to (but it better be a const char * if
you want it to point to a string literal):
const char *string1 = "This is the first string.";
const char *string2 = "This is the second string.";
const char *p = string1;
/* ... */
p = string2;
And you can store a string into an array of char:
char array[100] = "This is the initial string.";
/* ... */
strcpy(array, string1);
That will copy the string "This is the first string." into 'array'.
#include <string.h> for strcpy, and make sure you have enough space in
the destination array for the entire string, including the null character.
-Kevin