In the following program, i am expecting the for loop to stop after 3 elements.
But it keeps on going indefinitely and fails later on with a coredump.
- is
malloc() needed for
char*[]`
- would
strcmp
fail if i memset to 0?
.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char* str[10]; memset(str,0,10);
str[0]=malloc(sizeof(char)*(strlen("Sample")+1));
str[1]=malloc(sizeof(char)*(strlen("Sample")+1));
str[2]=malloc(sizeof(char)*(strlen("Sample")+1));
strcpy(str[0],"Sample");
strcpy(str[1],"Sample");
strcpy(str[2],"Sample");
int i=0;
for(i=0;strcmp("",str[i])!=0;i++)
{
printf("%d\n",i);;
}
return 0;
}
Edit:
Even with char* str[10]; memset(str,0,10*sizeof(char*));
the code still gives core dump
- is malloc() needed for char*[]`
There is hardly ever a need for malloc in C++.
In C, you usually do need malloc, but only if you need to allocate dynamically.
In general, having a char*[] does not mean that you necessarily need dynamic allocation and thus no need for malloc.
if i do not malloc for every element of array str[] , then wouldn't it be wrong to assign a string without allocating memory for this string?
A char* does not need to point to memory allocated with malloc. It can for example point directly to a string literal (only in C; in C++ you need a pointer to const). Or it can point to memory on the stack.
isn't char *str; strcpy(str,"sample") wrong if i dont allocate memory to str through malloc?
That is wrong, but not because you don't use malloc. It is wrong because you pass an uninitalised pointer to strcpy. Therefore the behaviour is undefined. It has nothing to do with malloc.
- would strcmp fail ...
It is unclear what you mean by "fail". There is no output that signifies a failure or error. For some inputs, the behaviour is undefined. While undefined behaviour is a failure of the programmer, there is no guarantee of behaviour that you might consider a failure.
... if i memset to 0?
If you pass a pointer to strcmp that is not a pointer to a null terminated string, then the behaviour of the program is undefined.
In the program that you show, you end up passing uninitialised pointer, or one that was memset to 0, and there is therefore no guarantee for them to be a pointer to a null terminated string. Therefore the behaviour of the program is undefined.
i'm passing a pointer pointing to 0(null), so dereferencing shouldn't face the problem of having no null terminated string right as we dont store anything in null location
Memset to 0 is not guaranteed to be null, as far as the standard is concerned. Even if probably is null on your system, 10 bytes is probably not enough for 4 pointers on that system, as pointed out by @ChristianGibbons, so you haven't actually initialised all of the pointers at all.
Even if you did initialise the pointers to null, a null pointer is not a pointer to a null terminated string, and therefore passing a null pointer to strcmp has undefined behaviour.
Summarizing everything stated in comments and other answers, there are at least three (or, if you want to be pedantic, four) problems here:
- You need
memset(str, 0, 10*sizeof(char *)
(but see #4 below).
- You need to check for null pointers before calling
strcmp
, using a condition like str[i] != NULL && strcmp("",str[i])!=0
in your for
loop.
- If you ever store 10 nonempty strings in the array, the loop's going to sail off the end, never finding an empty string.
- (pedantic)
memset
is not a good way to initialize an array of null pointers. (Strictly speaking it's not guaranteed to work at all.) As suggested by @user3121023 in a comment, a better way is char *str[10] = { NULL }
.
Instead of using an empty string (or a null pointer) as a marker for the end of your array of strings, you might consider keeping an explicit count in a separate variable. That's probably the more common approach.
Addendum. You were asking whether you needed to allocate the strings. Memory does need to be allocated for the strings, but you do not necessarily need to dynamically allocate it by calling malloc
. There are at least three ways to achieve the necessary allocation, and in two of them, the compiler does it for you. Here's an example of all three:
char sample1[] = "Sample 1";
char *sample2 = malloc(strlen("Sample 2") + 1);
strcpy(sample2, "Sample 2");
str[0] = "Sample 0";
str[1] = sample1;
str[2] = sample2;
for(i=0;strcmp("",str[i])!=0;i++)
You do dereference the unitialized pointer
for(i=0;str[i];i++)
But it will not work as this
memset(str,0,10);
Does not initialize the whole array
memset(str,0,10*sizeof(char *);