473,404 Members | 2,179 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

Reassigning array to string literal

Hi,
I am trying to reassign an array of char to a string literal by
calling a function.
In the function I use pointer-to-pointer since I want to reassign the
"string array pointer" to the string literal.
But the second printf seems to give me garbage.
Any advise on what I am doing wrong?

Thanx

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

static char *b = "This is a test";

int main( int argc, char **argv ) {

char a[10] = "abc";
int x;

printf( "1st : a = %s*\n", a );
call(&a);
printf( "2nd : a = %s*\n", a );

}

int call( char **input ) {
*input = b;
return 0;
}
Nov 14 '05 #1
4 5361

<so****@willowglen.com.sg> wrote in message
news:7e**************************@posting.google.c om...
Hi,
I am trying to reassign an array of char to a string literal by
calling a function.
In the function I use pointer-to-pointer since I want to reassign the
"string array pointer" to the string literal.
But the second printf seems to give me garbage.
Any advise on what I am doing wrong?

Thanx

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

static char *b = "This is a test";

int main( int argc, char **argv ) {

char a[10] = "abc";
to get correct output, you could try this

char *a = "abc";
int x;

printf( "1st : a = %s*\n", a );
call(&a);
printf( "2nd : a = %s*\n", a );

}

int call( char **input ) {
*input = b;
Here 'a' is constant and can not appear as a Lvalue. Thus, this is a
undefined behavior. am I correct?
return 0;
}

Nov 14 '05 #2
so****@willowglen.com.sg wrote:
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.

Thanx
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 <errno.h> or <stdlib.h>.

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.
return 0;
}


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
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #3
On 25 Dec 2003 23:31:05 -0800, so****@willowglen.com.sg wrote:
Hi,
I am trying to reassign an array of char to a string literal by
calling a function.
In the function I use pointer-to-pointer since I want to reassign the
"string array pointer" to the string literal.
But the second printf seems to give me garbage.
Any advise on what I am doing wrong?

Thanx

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

static char *b = "This is a test";

int main( int argc, char **argv ) {

char a[10] = "abc";
int x;

printf( "1st : a = %s*\n", a );
call(&a);
The only reason this does not generate a diagnostic is because you did
not include a prototype of call() in scope before you called the
function. If you had, you would have been informed that the argument
&a is not of type char** as required by call(). It is in fact of type
char(*)[10].

See for yourself. Place the following before the start of main():
int call(char**);
printf( "2nd : a = %s*\n", a );
Now that you have invoked undefined behavior, this can result in
anything. What I suspect happened is that call() has assembly code of
the form:

pick up sizeof(char*) bytes of data starting at the address input
points to
treat these bytes as a char* /*this value is the address of a*/
compute the address of b
store this computed value in the sizeof(char*) bytes starting
with the first byte of a /*as determined by step 2 above*/

If sizeof(char*) on your system is 2, then this replaces the first two
bytes of a (the 'a' and the 'b') with whatever two bytes form the
address of b. If sizeof(char*) is 4, it also replaces the 3rd and 4th
characters (the 'c' and the first '\0'). In either case, you still
have an array of char which is terminated by a '\0' so it is a
"string." Whether or not the bytes in the string are printable is a
matter of luck regarding the address of b and your character set.

}

int call( char **input ) {
*input = b;
return 0;
}


<<Remove the del for email>>
Nov 14 '05 #4
On Fri, 26 Dec 2003 15:48:54 +0530, "user" <no**@none.com> wrote:

<so****@willowglen.com.sg> wrote in message
news:7e**************************@posting.google. com...
Hi,
I am trying to reassign an array of char to a string literal by
calling a function.
In the function I use pointer-to-pointer since I want to reassign the
"string array pointer" to the string literal.
But the second printf seems to give me garbage.
Any advise on what I am doing wrong?

Thanx

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

static char *b = "This is a test";

int main( int argc, char **argv ) {

char a[10] = "abc";
to get correct output, you could try this

char *a = "abc";
int x;

printf( "1st : a = %s*\n", a );
call(&a);
printf( "2nd : a = %s*\n", a );

}

int call( char **input ) {
*input = b;


Here 'a' is constant and can not appear as a Lvalue. Thus, this is a
undefined behavior. am I correct?


Nope. a is not a constant. a is a pointer that points to data which
should be treated as constant. (Technically, it is not constant, just
unmodifiable.) For this discussion, let's assume that c does treat
string literals as constants. a would then be a pointer to const
char, not a const pointer. It is perfectly legal to reassign a to
point to the same data b points (which is another const char). In
both cases, a points to the first char of a const array of char or the
equivalent array of const char.

In fact, by defining a as a char* instead of a char[], you eliminate
the syntax error in the original code. (&a has type char(*)[10] while
call() is expecting a char**.) This error was undetected by the OP
because he failed to include a prototype of call() before calling the
function.

Therefore, while it doesn't do what the OP requested, you have in fact
removed the undefined behavior from the original code and created a
program without undefined behavior.
return 0;
}


<<Remove the del for email>>
Nov 14 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Mike S. Nowostawsky | last post by:
I tried using the "toUpperCase()" property to change the value of an array entity to uppercase BUT it tells me that the property is invalid. It seems that an array is not considered an object when...
7
by: Bo Sun | last post by:
hi: please take a look at the following code fragment: char* hello = "Hello World\n"; hello = 's'; why I cannot modify hello?
19
by: gaga | last post by:
I can't seem to get this to work: #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *names; char **np;
3
by: Kay | last post by:
ABC ASF DFS ASS ABC <--- Duplicate JJK I want to store above char in an arry, but I'm not sure I'm right or not anyone can guide me or give me some suggestions, Thx?
20
by: Petter Reinholdtsen | last post by:
Is the code fragment 'char a = ("a");' valid ANSI C? The problematic part is '("a")'. I am sure 'char a = "a";' is valid ANSI C, but I am more unsure if it is allowed to place () around the...
7
by: James Mcguire | last post by:
Hi, I frequently do non-initialisation type structure assignment via casting: e.g. struct s{int i,j,k;} mys; .... mys=(struct s){3,4,5};
20
by: bhalicki | last post by:
Hi all, In the following code I am trying to change the contents of a string: int main() { char *string="testing"; rename(string); return 0;
7
by: Sam Kong | last post by:
Hello! My question would not be very practical but just out of curiosity. In JavaScript, Array is a subclass of Object. Well maybe not exactly... but sort of... For normal objects, you can...
152
by: vippstar | last post by:
The subject might be misleading. Regardless, is this code valid: #include <stdio.h> void f(double *p, size_t size) { while(size--) printf("%f\n", *p++); } int main(void) { double array = { {...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.