-1

I want to know were a char* is stored, and how to make the a user input e.g. his name and then use printf to print it out...

char *name = "Adam"; 

/*where does this store itself? 
does the memory allocate the necessary memory stroage for this
please explain this simply and fully if you can
*/

//and btw

char name2[] = "Adam";

//what is the diffrence between name and name2

4 Answers4

4

Exactly where string literals get stored is largely up to the individual implementation; the only requirement is that the literal be visible to the entire program, and that it be allocated at program start and held until the program terminates.

Some platforms may store the literal in a different memory segment (such as .rodata).

As far as the difference between

char *name = "Adam";

and

char name2[] = "Adam";

a picture might help. Here's how things play out on my particular system:


           Item        Address   00   01   02   03
           ----        -------   --   --   --   --
         "Adam"       0x400ac0   41   64   61   6d    Adam
                      0x400ac4   00   22   41   64    ."Ad

           name 0x7fff39dbdb78   c0   0a   40   00    ..@.
                0x7fff39dbdb7c   00   00   00   00    ....

          name2 0x7fff39dbdb70   41   64   61   6d    Adam
                0x7fff39dbdb74   00   7f   00   00    ....

The string literal "Adam" is stored as an array of char starting at address 0x400ac0 (which is in the .rodata segment on my system).

The variable name is a pointer to char and contains the address of the string literal (my system is little-endian, so the address reads "backwards").

The variable name2 is an array of char whose contents are copied from the string literal.

Edit

What might help more is looking at generated machine code. Take the following program:

#include <stdio.h>

int main( void )
{
  char *name = "Adam";
  char name2[] = "Adam";

  printf("name = %s, name2 = %s\n", name, name2 );
  return 0;
}

I compiled it on a SLES 10 system with gcc as follows:

gcc -o name2 -std=c99 -pedantic -Wall -Werror name2.c -Wa,-aldh=name2.lst

which gave me the following assembler output in name2.lst:

GAS LISTING /tmp/ccuuqqGI.s                     page 1

   1                            .file   "name2.c"
   2                            .section        .rodata
   3                    .LC0:
   4 0000 4164616D              .string "Adam"
   4      00
   5                    .LC1:
   6 0005 6E616D65              .string "name = %s, name2 = %s\n"
   6      203D2025
   6      732C206E
   6      616D6532
   6      203D2025
   7                            .text
   8                    .globl main
  10                    main:
  11                    .LFB2:
  12 0000 55                    pushq   %rbp
  13                    .LCFI0:
  14 0001 4889E5                movq    %rsp, %rbp
  15                    .LCFI1:
  16 0004 4883EC10              subq    $16, %rsp
  17                    .LCFI2:
  18 0008 48C745F8              movq    $.LC0, -8(%rbp) 
  18      00000000                                      
  19 0010 8B050000              movl    .LC0(%rip), %eax
  19      0000                                          
  20 0016 8945F0                movl    %eax, -16(%rbp)
  21 0019 0FB60500              movzbl  .LC0+4(%rip), %eax
  21      000000
  22 0020 8845F4                movb    %al, -12(%rbp)
  23 0023 488D55F0              leaq    -16(%rbp), %rdx
  24 0027 488B75F8              movq    -8(%rbp), %rsi
  25 002b BF000000              movl    $.LC1, %edi
  25      00
  26 0030 B8000000              movl    $0, %eax
  26      00
  27 0035 E8000000              call    printf
  27      00
  28 003a B8000000              movl    $0, %eax
  28      00
  29 003f C9                    leave
  30 0040 C3                    ret
  31                    .LFE2:

As you can see, the string literals "Adam" and "name = %s, name2 = %s\n" are stored in the .rodata section (for read-only data items). Line 18 copies the address of the string literal to name, while lines 19 through 22 copy the contents of the string literal to name2.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

name and name2 both point to areas in memory that contain the same characters. That's about their only real relationship to each other.

name is a pointer, and only takes up sizeof(char*) bytes on its own. It does not own the memory its value points at. Since you've initialized it with a string literal, its value will be a pointer to a location containing the same sequence of bytes. That location will usually (but not always) be somewhere in a "constant data" section in your program. Might be the same section as the function's machine code lives in, but will often be a section specifically for constant values.

name2 is an array, and actually is the bunch of bytes the string takes up, rather than just pointing at it. If you'd said

char name2[] = { 'A', 'd', 'a', 'm', '\0' };

it'd mean the same thing, and would almost certainly compile to the same code.

Where the actual values of both variables are stored, depends almost entirely on where the line that declared them is. If they are in a function, both will have "automatic storage duration", which many people conflate with being "on the stack". If they're outside of any function, on the other hand, they will have "static storage duration", and will typically live in a part of your program that's reserved for global, mutable data.

The biggest difference (that you should care about yet) between name and name2, is that name2, being an array, is its own mutable sequence of bytes. Among other things, that means you can safely modify the string, as long as you don't read or write past the end of the array. All you know for sure about name's pointee is that it is a particular sequence of byte values. If you were to try to modify those bytes, you invoke what's called "undefined behavior"...which means the program has run off the rails, and all bets are off. C is within its rights to try to open a wormhole or order a dozen pizzas on your credit card. (The more likely outcome is a segfault. But relying on that to happen, or to be all that happens, is widely considered a bad idea.)

cHao
  • 84,970
  • 20
  • 145
  • 172
0

They are both allocated on the stack. One is a pointer, the other is an array of characters. Both create ONLY enough stack space to hold the number of chars provided, so you do NOT want to use them as user input... There are a million ways to get user input into a char* so I don't really want to cover it here, because you can do it with the STL, you can do it with C, you can do it with some sort of GUI, you can do it from a socket, you didn't specify... Look up commands like cin, to find out how to get user console input into a char *, but remember, you have to allocate your memory BEFORE you accept the input, and this is where things like buffer exploits happen. You probably want to look into creating a size, then allocate your input on the HEAP, not the STACK!

static const int SIZE_USER_NAME    = 40;
char *pszUsername = (char*)malloc(SIZE_USER_NAME);

If you allocate on the stack, you open yourself up to user inputting more than 40 chars, and trashing your stack, unless you are using some of the newer "secure" CRT functions, but you didn't mention anything about what this will run on, etc...

Hope that helps...

P.S. Don't forget to free(pszUsername); after you're done with it, or you'll leak memory too.

LarryF
  • 4,925
  • 4
  • 32
  • 40
  • 1
    Literal strings are typically stored in a text segment of the program's memory image. The answer by @John Bode is probably better. – Charles E. Grant Nov 13 '13 at 21:27
  • Sure, but he didn't specify the system this would be run on, so the actual executable plus the compiler to make it wasn't mentioned... But you are correct, so thanks for that correction... "Oh how easily we forget the little things.." heh... – LarryF Nov 15 '13 at 19:47
0

the first statement

char *name = "Adam";

does two things: 1. allocates memory for an unnamed array containing the characters'A','d','a','m','\0' in ROM (this is usually in the .text segment; so the array is actually in the code section) 2. creates a pointer called name which points to the unnamed array.

the second statement

char name2[] = "Adam";

creates the same string in ROM, for "Adam" but also allocates the size memory in the .data section(usually stack) and copies the contents of the literal string there. And creates a pointer name2 which points at the location in the data section.

The difference becomes apparent when trying to modify the value at the memory address indicated by the pointers:

name[0] = 'a'; //illegal
name2[0] = 'a'; //legal
Pandrei
  • 4,843
  • 3
  • 27
  • 44