DSPRelated.com
Forums

Pointer vs Array, or char * vs char[]

Started by William C Bonner March 20, 2006
I ran into a strange thing when compiling code for my DSP recently.  I 
would like to know what is going on, if this is something I don't 
understand in a difference of C vs C++, or something really strange in 
the Code Composer Studio Compiler / Linker.

My understanding was that a a char array was simply dealt with as a 
pointer to the chunk of memory that was declared.  The following code 
snippet that I was using, I would have expected to print the same line 
twice. It did not.  The second line was some other location from ram.  I 
have never run into a problem with something like this using MS Visual 
C, so I'm wondering if I'm doing something that is really wrong, or if

this is something that is strange happening in the linker, and if 
there's some way to tell the linker to fix what it is doing.  I'm not 
getting any linker errors, it is just not producing the proper output, 
and I'm wondering if this may be related to some other problems I have 
been having.

File1:

char ReallyBigString[] = "really big string\r\n";

main()
{
    printf(ReallyBigString);
    File2Subroutine();
}

File2:

extern char * ReallyBigString;
File2Subroutine()
{
    printf(ReallyBigString);
}
	
William,

if you declare the string this way:

    File1: 
    
    char str[] = "yeah\r\n"

    File2:

    extern char str[];

//or in this way:

    File1: 
    
    char *str = "yeah\r\n"

    File2:

    extern char *str;
	both printf() gives the correct result. It seems to be that both declarations,
local and extern must be identical so that the compiler understands it well.

Charles
	
I think I was able to fix the problem by building my example without 
sizing the string, but declaring it as an array in both places.  But I'm 
wondering if there is something fundamental that I'm not understanding.  
I would not be concerned if the problem generated an error while 
linking.  I'm concerned because it appeared to link properly, but 
accessed the wrong memory.  Since I've not got any memory protection in 
the DSP, tracing down a related problem is very hard. 

My concern is also there because I'm dealing with large amounts of code 
that are not my own, and The way I learned C first and C++ Second is 
fairly common among the people I'm working with.
	This example works as expected:
File1:

char ReallyBigString[] = "really big string\r\n";

main()
{
    printf(ReallyBigString);
    File2Subroutine();
}

File2:

extern char ReallyBigString[];
File2Subroutine()
{
    printf(ReallyBigString);
}

I would expect to be able to change where a pointer was pointing, but 
expect an array name to not want to be changed.

char BigString[] = "foo";        // Normal Array Declaration
char * ptrBigString = BigString; // Normal Pointer Declaration
char ArrBigString[] = BigString; // I would expect this to fail in the 
same file
	Andrew Oyaide wrote:
> I have had similar problem with this in the past. 
It looks like 
> it's a bug with the compiler/linker.  I got around this by declaring 
> the variable with the size e.g.
>  
> File1:
>
> char ReallyBigString[30] = "really big string\r\n";
>
> main()
> {
>     printf(ReallyBigString);
>     File2Subroutine();
> }
>
> File2:
>
> extern char ReallyBigString[30];
> File2Subroutine()
> {
>     printf(ReallyBigString);
> }
>
>
> >>> William C Bonner <wbonner@wbon...> 20/03/2006 19:58:16
>>>
> I ran into a strange thing when compiling code for my DSP recently.  I
> would like to know what is going on, if this is something I don't
> understand in a difference of C vs C++, or something really strange in
> the Code Composer Studio Compiler / Linker.
>
> My understanding was that a a char array was simply dealt with as a
> pointer to the chunk of memory that was declared.  The following code
> snippet that I was using, I would have expected to print the same line
> twice. It did not.  The second line was some other location from ram.  I
> have never run into a problem with something like this using MS Visual
> C, so I'm wondering if I'm doing something that is really wrong,
or if
> this is something that is strange happening in the linker, and if
> there's some way to tell the linker to fix what it is doing.  I'm
not
> getting any linker errors, it is just not producing the proper output,
> and I'm wondering if this may be related to some other problems I have
> been having.
>
> File1:
>
> char ReallyBigString[] = "really big string\r\n";
>
> main()
> {
>     printf(ReallyBigString);
>     File2Subroutine();
> }
>
> File2:
>
> extern char * ReallyBigString;
> File2Subroutine()
> {
>     printf(ReallyBigString);
> }
	
William, if you declare the string this way: File1: char str[] = "yeah\r\n" File2: extern char str[]; //or in this way: File1: char *str = "yeah\r\n" File2: extern char *str; both printf() gives the correct result. It seems to be that both declarations, local and extern must be identical so that the compiler understands it well. Charles
I think I was able to fix the problem by building my example without sizing the string, but declaring it as an array in both places. But I'm wondering if there is something fundamental that I'm not understanding. I would not be concerned if the problem generated an error while linking. I'm concerned because it appeared to link properly, but accessed the wrong memory. Since I've not got any memory protection in the DSP, tracing down a related problem is very hard. My concern is also there because I'm dealing with large amounts of code that are not my own, and The way I learned C first and C++ Second is fairly common among the people I'm working with. This example works as expected: File1: char ReallyBigString[] = "really big string\r\n"; main() { printf(ReallyBigString); File2Subroutine(); } File2: extern char ReallyBigString[]; File2Subroutine() { printf(ReallyBigString); } I would expect to be able to change where a pointer was pointing, but expect an array name to not want to be changed. char BigString[] = "foo"; // Normal Array Declaration char * ptrBigString = BigString; // Normal Pointer Declaration char ArrBigString[] = BigString; // I would expect this to fail in the same file Andrew Oyaide wrote: > I have had similar problem with this in the past. It looks like > it's a bug with the compiler/linker. I got around this by declaring > the variable with the size e.g. > > File1: > > char ReallyBigString[30] = "really big string\r\n"; > > main() > { > printf(ReallyBigString); > File2Subroutine(); > } > > File2: > > extern char ReallyBigString[30]; > File2Subroutine() > { > printf(ReallyBigString); > } > >>> William C Bonner 20/03/2006 19:58:16 >>> > I ran into a strange thing when compiling code for my DSP recently. I > would like to know what is going on, if this is something I don't > understand in a difference of C vs C++, or something really strange in > the Code Composer Studio Compiler / Linker. > > My understanding was that a a char array was simply dealt with as a > pointer to the chunk of memory that was declared. The following code > snippet that I was using, I would have expected to print the same line > twice. It did not. The second line was some other location from ram. I > have never run into a problem with something like this using MS Visual > C, so I'm wondering if I'm doing something that is really wrong, or if > this is something that is strange happening in the linker, and if > there's some way to tell the linker to fix what it is doing. I'm not > getting any linker errors, it is just not producing the proper output, > and I'm wondering if this may be related to some other problems I have > been having. > > File1: > > char ReallyBigString[] = "really big string\r\n"; > > main() > { > printf(ReallyBigString); > File2Subroutine(); > } > > File2: > > extern char * ReallyBigString; > File2Subroutine() > { > printf(ReallyBigString); > }
William--
This code worked just fine in my CCS setup. Are you missing something here?
 
--Bhooshan

 
On 3/21/06, William C Bonner <w...@wimsworld.com> wrote:
I ran into a strange thing when compiling code for my DSP recently.  I
would like to know what is going on, if this is something I don't
understand in a difference of C vs C++, or something really strange in
the Code Composer Studio Compiler / Linker.

My understanding was that a a char array was simply dealt with as a
pointer to the chunk of memory that was declared.  The following code
snippet that I was using, I would have expected to print the same line
twice. It did not.  The second line was some other location from ram.  I
have never run into a problem with something like this using MS Visual
C, so I'm wondering if I'm doing something that is really wrong, or if
this is something that is strange happening in the linker, and if
there's some way to tell the linker to fix what it is doing.  I'm not
getting any linker errors, it is just not producing the proper output,
and I'm wondering if this may be related to some other problems I have
been having.

File1:

char ReallyBigString[] = "really big string\r\n";

main()
{
   printf(ReallyBigString);
   File2Subroutine();
}

File2:

extern char * ReallyBigString;
File2Subroutine()
{
   printf(ReallyBigString);
}



--
-------------------------------
"I've missed more than 9000 shots in my career.
I've lost almost 300 games. 26 times I've been trusted to take the game winning shot and missed.
I've failed over and over again in my life.
And that is why I succeed."
        -- Michael Jordan
--------------------------------

char ReallyBigString[] = "really big string\r\n";

 

extern char * ReallyBigString

 

These ARE NOT the same thing. One of them says that ReallyBigString is the address of a pointer to an array of characters. The other says the ReallyBigString is address of the beginning of an array of characters. Arrays and pointers are NOT that same thing in C.

 

I’ll Try to draw a picture…

 

(1) ReallyBigString[] = "really big string\r\n";

 

ReallyBigString-------> |r|e|a| …|\r|\n|\0|

 

 

(2) extern char * ReallyBigString -------> [an addresss]-------> |r|e|a| …|\r|\n|\0|

 

When these are mixed disaster ALWAYS strikes… de-referencing ReallyBigString in file #2 (*ReallyBigString) takes the first n bytes (where n = the number of bytes in an address” of the string “really big string \r\n” and tries to use them as the address of the array *ReallyBigString points to…

 

I am in a hurry right now. If this is not clear let me know and I will try to explain it better.

 

 

Note that inside a function call – eg void AccessReallyBigString1(char *String) and  void AccessReallyBigString2(char String[]) – they are interchangeable. This is only a side effect of C’s pass by value semantics.

 

 

 

 

 

 

 

-----Original Message-----
From: c...@yahoogroups.com [mailto:c...@yahoogroups.com] On Behalf Of Bhooshan Iyer
Sent: Tuesday, March 21, 2006 11:22 AM
To: William C Bonner
Cc: c...@yahoogroups.com
Subject: Re: [c6x] Pointer vs Array, or char * vs char[]

 

William--

This code worked just fine in my CCS setup. Are you missing something here?

 

--Bhooshan

 

On 3/21/06, William C Bonner <w...@wimsworld.com> wrote:

I ran into a strange thing when compiling code for my DSP recently.  I
would like to know what is going on, if this is something I don't
understand in a difference of C vs C++, or something really strange in
the Code Composer Studio Compiler / Linker.

My understanding was that a a char array was simply dealt with as a
pointer to the chunk of memory that was declared.  The following code
snippet that I was using, I would have expected to print the same line
twice. It did not.  The second line was some other location from ram.  I
have never run into a problem with something like this using MS Visual
C, so I'm wondering if I'm doing something that is really wrong, or if
this is something that is strange happening in the linker, and if
there's some way to tell the linker to fix what it is doing.  I'm not
getting any linker errors, it is just not producing the proper output,
and I'm wondering if this may be related to some other problems I have
been having.

File1:

char ReallyBigString[] = "really big string\r\n";

main()
{
   printf(ReallyBigString);
   File2Subroutine();
}

File2:

extern char * ReallyBigString;
File2Subroutine()
{
   printf(ReallyBigString);
}




--
-------------------------------
"I've missed more than 9000 shots in my career.
I've lost almost 300 games. 26 times I've been trusted to take the game winning shot and missed.
I've failed over and over again in my life.
And that is why I succeed."
        -- Michael Jordan
--------------------------------

The original code definitely does not work. What I've changed was the printf operators, where a format was added, and the most important change was in the extern declaration in the File2. A good excersise in handling strings :) Regards, Andrew File1: #include char ReallyBigString[] = "really big string\r\n"; void File2Subroutine (void); int main (void) { printf ("%s", ReallyBigString); File2Subroutine (); } File2: #include extern char ReallyBigString[]; void File2Subroutine (void) { printf ("%s", ReallyBigString); } Regards, Andrew > Date: Mon, 20 Mar 2006 11:58:16 -0800 > From: William C Bonner > Subject: Pointer vs Array, or char * vs char[] > > I ran into a strange thing when compiling code for my DSP recently. I > would like to know what is going on, if this is something I don't > understand in a difference of C vs C++, or something really strange in > the Code Composer Studio Compiler / Linker. > > My understanding was that a a char array was simply dealt with as a > pointer to the chunk of memory that was declared. The following code > snippet that I was using, I would have expected to print the same line > twice. It did not. The second line was some other location from ram. I > have never run into a problem with something like this using MS Visual > C, so I'm wondering if I'm doing something that is really wrong, or if > this is something that is strange happening in the linker, and if > there's some way to tell the linker to fix what it is doing. I'm not > getting any linker errors, it is just not producing the proper output, > and I'm wondering if this may be related to some other problems I have > been having. > > File1: > > char ReallyBigString[] = "really big string\r\n"; > > main() > { > printf(ReallyBigString); > File2Subroutine(); > } > > File2: > > extern char * ReallyBigString; > File2Subroutine() > { > printf(ReallyBigString); > } >
The original code definitely does not work. What I've changed was
the printf operators, where a format was added, and the most
important change was in the extern declaration in the File2.

A good excersise in handling strings :)

Regards,

Andrew

File1:

#include <stdio.h>

char ReallyBigString[] = "really big string\r\n";

void File2Subroutine (void);

int main (void)
{
    printf ("%s", ReallyBigString);
    File2Subroutine ();
}

File2:

#include <stdio.h>

extern char ReallyBigString[];

void File2Subroutine (void)
{
    printf ("%s", ReallyBigString);
}
	Regards,

Andrew
	> Date: Mon, 20 Mar 2006 11:58:16 -0800
> From: William C Bonner <wbonner@wbon...>
> Subject: Pointer vs Array, or char * vs char[]
>
> I ran into a strange thing when compiling code for my DSP recently.  I
> would like to know what is going on, if this is something I don't
> understand in a difference of C vs C++, or something really strange in
> the Code Composer Studio Compiler / Linker.
>
> My understanding was that a a char array was simply dealt with as a
> pointer to the chunk of memory that was declared.  The following code
> snippet that I was using, I would have expected to print the same line
> twice. It did not.  The second line was some other location from ram.  I
> have never run into a problem with something like this using MS Visual
> C, so I'm wondering if I'm doing something that is really wrong,
or if
> this is something that is strange happening in the linker, and if
> there's some way to tell the linker to fix what it is doing.  I'm
not
> getting any linker errors, it is just not producing the proper output,
> and I'm wondering if this may be related to some other problems I have
> been having.
>
> File1:
>
> char ReallyBigString[] = "really big string\r\n";
>
> main()
> {
>    printf(ReallyBigString);
>    File2Subroutine();
> }
>
> File2:
>
> extern char * ReallyBigString;
> File2Subroutine()
> {
>    printf(ReallyBigString);
> }
>

William- > (1) ReallyBigString[] = "really big string\r\n"; > > ReallyBigString---> |r|e|a|...|\r|\n|\0| > > (2) extern char * ReallyBigString ---> [an address]---> |r|e|a|...|\r|\n|\0| > > When these are mixed disaster ALWAYS strikes... de-referencing > ReallyBigString in file #2 (*ReallyBigString) takes the first > n bytes (where n = the number of bytes in an address of the > string "really big string \r\n" and tries to use them as the > address of the array *ReallyBigString points to. Maybe you can check what Wayne is saying is by looking at the pointer you end up using in case 2? Does it have a value something like 0x7265616c ("real")? I'm assuming you are using far calls and little-endian mode. -Jeff