Quick c question: How to know the length of a char* foo[]?
Thanks.
You can't. Not without knowing something about what is inside of the pointers, or storing that data ahead of time.
You mean the number of strings in the array?
If the array was allocated on the stack in the same block, you can use the sizeof(foo)/sizeof(foo[0]) trick.
const char *foo[] = { "abc", "def" };
const size_t length = sizeof(foo)/sizeof(foo[0]);
If you're talking about the argv passed to main, you can look at the argc parameter.
If the array was allocated on the heap or passed into a function (where it would decay into a pointer), you're out of luck unless whoever allocated it passed the size to you as well.
If the array is statically allocated you can use the sizeof() function. So sizeof(foo)/sizeof(char *) would work.
If the array was made dynamically, you're in trouble! The length of such an array would normally be explicitly stored.
EDIT:
janks is of course right, sizeof is an operator.
Also it's worth pointing out that C99 does allow sizeof on variable-size arrays. However different compilers implement different parts of C99, so some caution is warranted.
Related
I am pretty new to C and I am trying to read the user input (some sentence or string in general) and then I want to create an array based on the input lenght. Is there a reasonable way to do it? Thanks for answers
Just for an overview of why all the answers are suggesting pointers instead of arrays:
When I was learning C one thing that helped was to understand arrays and pointers and how similar they are.
For the most part, they can have the same syntax, you can use * syntax with either or you can use [] syntax with either.
The differences are:
1) Arrays have memory allocated for them by the system and pointers don't, you have to "set" a pointer to some memory that you have allocated.
2) I don't think arrays can change where arrays point, they always point at their pre-allocated spot.
Since arrays are pre-allocated and can't be repointed, you want a pointer. You can treat it exactly as an array (You can use [] syntax) but you have to allocate memory for it first.
So for example, if a array with and p is a pointer, a[0]=1, *a=1, p[0]=1 and *p=1 are all identical functions, and while *++p=1 is valid, I don't think *++a=1 is valid because you can't change where a points.
So the short version would be, you need a pointer, not an array, and to change how much is allocated, you allocate the new size (With malloc or something similar), copy what you want to retain over and free the old space (Or you might be able to increase the size of the first one--realloc?, not sure, my C is decades old)
malloc/free, in the case of strings a strlen will get you it's length.
You can use malloc to allocate new memory, Note that since C's memory isn't managed (contrary to Java, Python or any other high level language), you will have to free the memory once you are done using it.
int arr_size = 0;
int* arr;
printf("Please enter a size to the array:");
scanf("%d", &arr_size);
arr = malloc(arr_size * sizeof(int))
// Use array
free(arr);
void *malloc(size_t size);
The malloc() function allocates size bytes and returns a pointer to
the allocated memory. The memory is not initialized. If size is 0,
then malloc() returns either NULL, or a unique pointer value that can
later be successfully passed to free().
It depends on the standard you're compiling against and your compiler. You can only rely on variable length arrays in C99
The only way to be certain is to use malloc, though you need to ensure you free the memory afterwards:
int length;
// Do something to set the size
// Allocates a contiguous block of memory that is
// (length * size of a char primitive) in length
char *array = (char *)malloc(length * sizeof(char));
// Do whatever you need do to with the array
free(array);
In C, declaring a variable as a pointer (char *a) and as an array (char a[3]) allows you to use that variable in exactly the same way. The only difference is that with a pointer you need to allocate and free the memory yourself, while with the array that block of memory is given to you automatically and it is freed when it goes out of scope.
With the code above, you can still access each individual character via an index like so:
array[0] = 'f';
array[1] = 'o';
array[3] = 'o';
I'd like to have an array of fixed length strings in c in the form of a pointer so I can dynamically allocate the memory for it.
I can see plenty of reference to arrays of pointers to string, but not to what I want to achieve.
What I want is to be able to declare a pointer to char[MAX_STRING_LENGTH] so I can then dynamically allocate a contiguous block of memory for all the strings:
char *(names[MAX_STRING_LENGTH]); // This won't work
names = (some cast)malloc(NUM_STRINGS * MAX_STRING_LENGTH);
And then access the array of strings:
strcpy(name, names[stringIndex]);
How do I declare the variable and cast the pointer from malloc?
You declare names as an array of pointers, not a pointer to arrays. That would be
char (*names)[MAX_STRING_LENGTH]; // Names is a pointer to an array of char
Now you can allocate memory for the pointer:
// Allocate memory for NUM_STRINGS arrays and assign the pointer to names
names = malloc(NUM_STRINGS * sizeof *names);
You want a pointer to array MAX_LENGTH of char Using cdecl (note that cdecl doesn't understand things like MAX_LENGTH so we use a number here instead):
% cdecl
Type `help' or `?' for help
cdecl> declare names as pointer to array 256 of char;
char (*names)[256]
we get that the proper declaration is
char (*names)[MAX_LENGTH];
However this still isn't very useful, because reallocation would be very costly because it possibly could have to move each and every string to a new location. So I suggest that you'd still use a pointer to pointer to char.
Someprogrammerdude already provided the solution.
Generally, since C/C++ types can become somewhat tricky, you can utilize any half-decent IDE to look up correct type definitions.
This trick relies on the C++11 auto keyword, which determines a variable type from its initializer. The resulting type can still be used in other C/C++ versions and is not restricted to C++11.
In your case, specify a type that you know and that can be transformed into the type you want:
char names[10][10];
Then assign an auto variable with the desired type:
auto names2 = &names[0];
Inspect the actual type of names2 and use it. For example, in Visual Studio, just hover the mouse over names2 to see the type. Most IDEs will display the type by hovering over either the auto keyword or the defined variable.
For the example, hovering would reveal the type char (*names2)[10].
You need to understand the concept of Pointer Arrays.Refer the book "The C programming Language" By Dennis M. Ritchie & Kernighan. Specially the pointer and array part.There are some amazing stuffs to read. Probably you will get a more deeper concept of pointers and arrays after reading and solving some problems given in the book.
Do these two pieces of C code achieve the same goal:
char ** p;
p = malloc(sizeof(char*) * 10);
--------------------------------
char * z[10];
It seems like they can be used identically:
p[1] = "Foo";
*(p+2) = "Bar";
---------------------
z[1] = "Foo";
*(z+2) = "Bar";
Is there a difference?
If you just store and retrieve values from the array, or malloc-allocated area, they work the same.
There are differences, though. sizeof and & work differently, you need to explicitly free the malloc-allocated area to release the memory, and you can change its size with realloc.
in terms of use and functionality, there really is no difference except in how you plan to use it.
An example of what I mean is that I could use a double pointer for iterating and dereferencing the whole multidim array.
not to mention that when you malloc, you need a matching free when you're done with it.
Of course, you should only malloc when you think you really need it or you need a massive amount of memory.
Last part I want to say is that with the pointer array, you cannot dereference the individual characters without using the subscript operator []
C memory is split into several types, stacks -for function calls and local variables, and then there is heap -for malloced objects. The stack usually has smaller size than the heap. As a result, if you try to allocate a huge array in stack you might exceed the stack's storage space causing segfault.
In this case when you malloc an array, heap memory is being used .And it will exist until it is explicitly deallocated with free. This is useful in cases where you are using large array size.
Whereas in the first case you are declaring the array in stack,which lives only as long as the function that calls it exists.
Since the array size is small here, both works. But for larger arrays, malloc'ing is recommended to avoid segfault.
there are many similar questions regarding this Topic, but they do not answer the following question:
Taking a swing
I am going to take a swing, if you want go straight to the question in the next heading. Please correct me if I make any wrong assumptions here.
Lets assume, I have this string declaration
char* cpHelloWorld = "Hello World!";
I understand the Compiler will make a char* to an anonymous Array stored somewhere in the Memory (by the way: where is it stored?).
If I have this declaration
char cHelloWorld[] = "Hello World!";
There will be no anonymous Array, as the Compiler will create the Array cHelloWorld right away.
The first difference between these two variables is that I can change cpHelloWorld, whereas the Array cHelloWorld is read-only, and I would have to redeclare it if I want to Change it.
My question is following
cpHelloWorld = "This is a pretty long Phrase, compared to the Hello World phrase above.";
How does my application allocate at runtime a new, bigger (anonymous) Array at runtime? Should I use this approach with the pointer, as it seems easier to use or are there any cons? On paper, I would have used malloc, if I had to work with dynamic Arrays.
My guess is that the Compiler (or runtime Environment?) creates a new anonymous Array every time I change the Content of my Array.
char* cpHelloWorld = "Hello World!";
is a String Literal stored in read-only memory. You cannot modify the contents of this string.
char cHelloWorld[] = "Hello World!";
is an array of char initialized to "Hello World!\0".
(note: where the brackets are placed)
The amount of memory allocated at run-time by the compiler is set by the initialization "This is a pretty long ... phrase above."; The compiler will initialize the literal allowing 1 char for each char in the initialization string +1 for the required nul-terminating character.
Whether you use a statically declared array (e.g. char my_str[ ] = "stuff";) or you seek to dynamically allocate storage for the characters, largely depends on whether you know what, and how much, of whatever you wish to store. Obviously, if you know beforehand what the string is, using a string literal or an initialized array of type char is a simple way to go.
However, when you do NOT know what will be stored, or how much, then declaring a pointer to char (e.g. char *my_string; and then once you have the data to store, you can allocate storage for my_string (e.g. my_string = malloc (len * sizeof *my_string); (of course sizeof *my_string will be 1 for character arrays, so that can be omitted) (note: parenthesis are required with sizeof (explicit type), e.g. sizeof (int), but are optional when used with a variable)
Then simply free whatever you have allocated when the values are no longer needed.
As a matter of fact all strings known to the compiler at compile-time are allocated in the data segment of the program. The pointer itself is located on the stack.
There is no memory allocation at run-time, so it is nothing like malloc. There are no performance drawbacks here.
Each of the constant "anonymous" strings used in these contexts exists at its fixed address. The only dynamic part is the actual pointer assignment. You should get the same string address each time you execute a specific pointer assignment from a specific anonymous string (each string has its own address).
I came around this similar question.
But the advantage I have is that i know that each string is 260 char long.
Any hope?
int noOfStrings = sizeof(stringArray)/sizeof(stringArray[0]);
This doesn't work.
As it says. You cannot (unless it's a variable local to the function). Because of the way arrays are passed they degrade to pointers and all size information is lost (outside of the context of where the array was created because the compiler cannot make assumptions about it anymore).
You must explicitly pass the size (or always pass the same size).
What you posted would work if stringArray were declared globally or that statement was inside the function where you declared it.
It depends on how stringArray was declared.
That works when:
int main()
{
char stringArray[500];
int noOfStrings = sizeof(stringArray)/sizeof(stringArray[0]);
...
}
but not in:
int function(char *stringArray)
{
int noOfStrings = sizeof(stringArray)/sizeof(stringArray[0]);
...
}
In the first case, stringArray is a constant of type char[500], and the sizeof gives the number of bytes allocated for the array.
In the second case, stringArray is a pointer to char, and sizeof gives the size of the pointer.
They are two completely different things, just look similar.
Please post your code. Your specific solution which wants to compute a value at run time is not possible at first glance.
However, you might be able to code/define a macro as:
#define strsize sizeof(stringArray) / sizeof(char *)
if stringArray is an array of char pointers, but without seeing your source it is difficult to recommend a specific solution.
Sometimes a solution while not directly possible is still achievable but by other methods!!