问题
I'm new in programming in C and now I'm studying strings.
My question is: if I allocate a string using malloc (as in the code below), is the NULL character automatically inserted at the end of the string?
I find an answer in another question here, and it seems that the NULL character is not automatically included.
But here comes the problem: I know functions like strlen don't work if there isn't the NULL character, and in this code I use it and it works. So I think there is \0 at the end of my string, even if I don't write it anywhere.
What's the answer?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) {
char *stringa1;
int n;
int i;
printf("How many characters in the string? ");
scanf("%d", &n);
stringa1 = (char*) malloc(n*sizeof(char));
printf("Insert the string: ");
scanf("%s", stringa1);
free(stringa1);
return 0;
}
回答1:
malloc() returns a void* pointer to a block of memory stored in the heap. Allocating with malloc() does not initialize any string, only space waiting to be occupied.To add a null-terminating character, you either have to do this yourself, or use a function like scanf(), which adds this character for you. Having said this, you need to allocate space for this \0 character beforehand.
Your malloc() call should be this instead:
stringa1 = (char*) malloc((n+1)*sizeof(char)); /*+1 for '\0' character */
Note: You don't need to cast return of malloc. For more information, read this.
Another thing to point out is sizeof(char) is 1, so multiplying this in your malloc() call is not necessary.
You also need to check if malloc() returns NULL. This can be done like this:
if (stringa1 == NULL) {
/* handle exit */
Also, you can only use strlen() on a null-terminated string, otherwise this ends up being undefined behaviour.
Once scanf() is called, and the stringa1 contains some characters, you can call strlen() on it.
Additionally, checking return of scanf() is also a good idea. You can check it like this:
if (scanf("%d", &n) != 1) {
/* handle exit */
Your code with these changes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *stringa1 = NULL;
size_t n, slen;
printf("How many characters in the string? ");
if (scanf("%zu", &n) != 1) {
printf("Invalid input\n");
exit(EXIT_FAILURE);
}
stringa1 = malloc(n+1);
if (stringa1 == NULL) {
printf("Cannot allocate %zu bytes for string\n", n+1);
exit(EXIT_FAILURE);
}
printf("Insert the string: ");
scanf("%s", stringa1);
slen = strlen(stringa1);
printf("String: %s Length: %zu\n", stringa1, slen);
free(stringa1);
stringa1 = NULL;
return 0;
}
回答2:
if I allocate a string using malloc (as in the code below), is the NULL character automatically inserted at the end of the string?
No. malloc() returns a block of uninitialized memory.
I know functions like 'strlen' don't work if there isn't the NULL character, and in this code I use it and it works. So I think there is '\0' at the end of my string, even if I don't wrote it nowhere.
scanf() inserts the null byte ('\0') for you when you use %s format specifier (assuming scanf() succeeded).
From man scanf():
s Matches a sequence of non-white-space characters; the next pointer must be a pointer to the initial element of a character array that is long enough to hold the input sequence and the terminating null byte ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.
(emphasis mine).
By the way, you should do error checking for scanf() and malloc() calls.
回答3:
The definition of "string" in C is a sequence of characters, terminated by a null character.
To allocate memory for a string, count the chracters (e.g. strlen) and add 1 for this terminating null character.
Functions like scanf and strcpy add the null character; a function like strncpy doesn't always do that.
回答4:
malloc returns pointer to an uninitialized memory extent.
If you want that the memory extent would be initialized by zeroes then you can use another standard function calloc instead of malloc.
Take into account that usually such a question like this
printf("How many characters in the string? ");
imply that the terminating zero is not counted. So you have to allocate one more byte of memory. For example
stringa1 = ( char* )malloc( ( n + 1 ) *sizeof( char ) );
or
stringa1 = ( char* )calloc( n + 1, sizeof( char ) );
In the last case you may apply the function strlen which returns 0 because the memory extent is zero-initialized.
This call of scanf
scanf("%s", stringa1);
is unsafe. It is better to use fgets instead. For example
fgets( stringa1, n + 1, stdin );
This function can append the string with the new line character. To remove it from the string you can write
stringa1[strcspn( stringa1, "\n" )] = '\0';
来源:https://stackoverflow.com/questions/41830461/allocating-string-with-malloc