-3

I do not understand very well.

char *string;
string = malloc(1); 
if (string == NULL) {
    printf("Couldn't able to allocate requested memory\n")
} else {
    string = "testing";
}
printf("Dynamically allocated memory content : %s\n\n\n", string );

string "testing" have 7 characters + null for the end of the string. If I allocated memory with malloc(1), I am reserved 1byte of memory, respectively I am reserved memory for 1 character because 1 character have a 1byte of memory. But when I printed this string result is "testing" but I guess that should be printed "t" because of reserve 1 byte of memory for 1 character.

UkFLSUI
  • 5,509
  • 6
  • 32
  • 47
respect99
  • 63
  • 1
  • 7

5 Answers5

3

You are leaking the one byte you allocated. Let's make that with addresses: (Smaller addresses for more clarity) Suppose malloc returns a pointer to the address 0x4000. You store it in string. Now string is a pointer pointing to 0x4000. "testing" has for example the address 0x1200. string points now to 0x1200. You give printf a the address 0x1200 and there is the string "testing" ==> testing is written onto the console.

JCWasmx86
  • 3,473
  • 2
  • 11
  • 29
2

When you deal with pointers you need to think differently.

The following statement makes string point to a memory location somewhere in the heap that is 1 byte long.

string = malloc(1);

When you assign string to point to a literal, you make string point to another place in memory.

string = "testing"

the byte that previous was pointed to by string is leaked i.e. it has no longer a reference.

          +---+
string -> |   |
          +---+ 


             +---+
string       |   |
       \     +---+
        \    +-----------+
         --> | testing\0 |
             +-----------+
         
AndersK
  • 35,813
  • 6
  • 60
  • 86
1

You do not write the content of the string "testing" neither fully nor partwise into the dynamic memory allocated by malloc() with:

string = "testing";

Instead, you overwrite the pointer string to point to read-only memory filled with the string "testing".

Note that string literals like "testing" gain a pointer to a read-only location.


When you try to print the content, where string points to with:

printf("Dynamically allocated memory content : %s\n\n\n", string );

it prints the string "testing" allocated in this read-only memory and not a string anyhow stored inside of the allocated dynamic memory.

The waste of the unnecessary allocated 1 byte is a memory leak.

1
int x = 0;
x = 42;

The end result is exactly the same as

int x = 42;

without going through 0 first.

Pointers are not magical.

char* string = malloc(...);
string = "testing";

The end result is exactly1 the same as

char* string = "testing";

without going through malloc first.

A string is not a pointer. A string is an null-terminated array of characters. In order to allocate a string, you:

  1. Allocate an array of characters of suitable length.
  2. Copy a null-terminating sequence of characters to said array (which is entirely different from copying a pointer).

So

// 1 Allocate an array of characters of suitable length
char *string = malloc(strlen("testing")+1); 
// note suitable length
// the variable `string` points to the first character of the array just allocated

// 2 Copy a null-terminating sequence of characters to said array
strcpy (string, "testing"); 
// other ways of copying strings exist

Checking the return value of malloc is omitted for brevity only.


1 There is some difference: malloc allocates memory, which the first fragment happily discards, resulting in a memory leak. This difference is, however, undetectable by your program, which means the observable program behaviour is exactly the same. You can only detect the difference from the outside of the program, for example, by tracing it with a debugger.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

Like the other answers point out, you’re assigning the address of the string literal to string - you are not copying the contents of the string literal to the memory string points to.

The problem is that you cannot use the = operator to assign strings, because strings (including string literals like "testing") are stored as arrays of character type, and array expressions “decay” to pointer expressions under most circumstances.

To copy string contents from one array to another, you need to use a library function like strcpy, strncpy, or memcpy:

strcpy( string, "testing" );

In this case, since string points to a buffer that isn’t big enough to store the contents of the literal, you wind up undefined behavior - you might get a runtime error, you might not. You might overwrite something important, you might not. Neither the compiler nor the runtime environment are required to issue any kind of warnings.

Unfortunately it’s up to you, the programmer, to make sure your target buffer is either large enough to store the string or that you truncate the string so that it fits into the target buffer.

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