Hi, I get the error "warning: array ‘str’ assumed to have one element [enabled by default]" when I am trying to fill in values inside the string array.

#include<stdio.h>
#include<string.h>
#include<malloc.h>

char* str[];
int i = 0;

int main(void)
{
 for(i=0;i<5;i++)
 str[i] = (char*)malloc(200 * sizeof(char));
  
 strcpy(str[0],"hello");
 strcpy(str[1],"my"); 
 strcpy(str[2],"name"); 
 strcpy(str[3],"is"); 
 strcpy(str[4],"tubby"); 
 
 for(i=0; i<5; i++)
 printf("[%s]",str[i]);

 return 0;
}

What is the cause for this warning? Yes the output is getting displayed correctly, but why the warning ?
Please note that I have already done a malloc and created a space of 200 characters for each of the strings.

Dani AI

Generated

Short answer: the compiler is warning because the file-scope array was declared without a size or initializer, which the C standard treats as a tentative definition; if no real definition appears in the translation unit the array is completed as a one-element array, so the compiler warns that it “assumed to have one element.” This is why the message appears even though the program may print what was expected. C99 draft. (landley.net)

That output working is accidental. Assigning to str[1]..str[4] when the array is actually one element is an out-of-bounds write — undefined behavior that can silently corrupt memory or crash later. The practical fixes are the ones already shown by other posters: give the array an explicit size (so the compiler allocates storage for five pointers), allocate the pointer array dynamically, or use a static initializer of string literals if the strings are constant (as , , and hinted). See why out-of-bounds array access is undefined. (stackoverflow.com)

Practical tips: include <stdlib.h> (not nonstandard <malloc.h>), do not rely on implicit or accidental overrun, and avoid unnecessary casts of malloc in C (they can hide prototype problems). Enable warnings and run memory checks (compile with sanitizers such as AddressSanitizer or use Valgrind) to catch these errors early. Add explicit bounds, check malloc returns, and prefer bounded copy functions to avoid buffer overruns. AddressSanitizer docs. Why use <stdlib.h> (not <malloc.h>). (clang.llvm.org)

Recommended Answers

All 9 Replies

What happens if you give str an initial size of 5?

What happens if you give str an initial size of 5?

sorry thines01, didn't get you. You mean , what if you give char* str[5] ?

What happens if you give str an initial size of 5?

- you are absolutely right, when I initialize as char* str[5] , it works fine. How is that ? Please explain.

char* str[] is the same thing as char** str; , which is a two dimensional array where both dimensions are unspecified and must be allocated at runtime. char* str[5]; is also a two dimensional array, but in this case you have hard-coded one of the dimensions to be of length 5. That means where is room to store 5 strings of unspecified length.

You shouldn't code like that.

Be specific in what you want the compiler to reserve for space.

In fact, if you create an array, and it has almost no space, you can "get away" with overrunning it, by several char's, or pointers to char's, even integers. Usually about 7, but it depends on the compiler, and system.

C does not guarantee that a program with inadequate space will crash - it may run, if you're lucky. Extend this program out to 20 strings, and I'm thinking it's a crasher - but again, I don't code like this, and I've tested it only a few times, with integers.

No, you shouldn't be casting the return from malloc, but most importantly, you should be making your space, adequate and explicit. IMO, this:

char str[n][m] is a true two dimensional array
char *str[n] is an array of pointers to chars, which is very similar to a true 2D array, but not the exact same thing.

Work it clockwise:

str -> [] string is an array
[] -> * of pointers
* - > circles around to the end of the line, then continues on around still going clockwise around str, to find

char

In a spiraling clockwise loop.

You shouldn't code like that.

Be specific in what you want the compiler to reserve for space.

In fact, if you create an array, and it has almost no space, you can "get away" with overrunning it, by several char's, or pointers to char's, even integers. Usually about 7, but it depends on the compiler, and system.

C does not guarantee that a program with inadequate space will crash - it may run, if you're lucky. Extend this program out to 20 strings, and I'm thinking it's a crasher - but again, I don't code like this, and I've tested it only a few times, with integers.

No, you shouldn't be casting the return from malloc, but most importantly, you should be making your space, adequate and explicit. IMO, this:

char str[n][m] is a true two dimensional array
char *str[n] is an array of pointers to chars, which is very similar to a true 2D array, but not the exact same thing.

Work it clockwise:

str -> [] string is an array
[] -> * of pointers
* - > circles around to the end of the line, then continues on around still going clockwise around str, to find

char

In a spiraling clockwise loop.

- can u maybe rewrite the important parts of the code in the way you would have written. Will help me to understand easier and better.

Hi, I get the error "warning: array ‘str’ assumed to have one element [enabled by default]" when I am trying to fill in values inside the string array.

#include<stdio.h>

int main(void) {
   //unless there's a good reason (like to use global memory), variables are local
   //here only, the compiler will count the number of strings I need, for me
   char *str[]; {"hello","my","name","is","tubby"}; 
   int i = 0;

    for(i=0; i<5; i++)
       printf("%s\n",str[i]);

    return 0;
}

That's how I'd write it.

Except it should be char *str[] = {"hello","my","name","is","tubby"}; :-)

Yes, only one semi-colon on that line of code! Thanks, Rubberman.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.