I'm trying to write a program that reads multiple files and stores all the words in one array of strings. Here are some parts of the code:
This is the array that I'm supposed to put the words in:
I also dynamically allocate memory to this array and free it, so the issue is not that. For some reason, after the while loop, when I try to print out the array, it is empty, like nothing was written to it.
If you need any other parts of the code, let me know, I'll gladly post it.
Assuming that word_collection.all_words is valid for all indexes you're using, then the assignment
word_collection.all_words[wc_pos++] = word;
will make all elements of word_collection.all_words point to the exact same location: The first element of the single word array.
This is one problem, there's also another possible problem with this: If word is not a global variable, then as soon as the function that defines word returns, the life-time of word will end, making all those pointers invalid.
To solve both those problems you need to allocate memory for each element as well, and copy the string from word. This can be done by the commonly available strdup function:
word_collection.all_words[wc_pos++] = strdup(word);
Of course you have to remember to free all the pointers returned by strdup.
Related
How can I read in C a line from the console to not initialize a some array like int buf[30];? I need to allocate it once and required length, i.e. to I can know input characters count before read it...
Is it possible in C?
There is no way to know the number of characters available in standard input before reading them. You can, however, use getline(3), which will read until \n and then return the data in a dynamically-allocated buffer holding the data (along with the size of that buffer). You must free the buffer when you're done with it.
You should be aware that this will routine will block until it reads a newline. It's also difficult to use this routine safely, as malformed inputs are not handled well. (What if the input has no newline?) This is one of the reasons many applications often read a fixed length input.
I suspect that what you are requesting is about dynamic memory.
With dynamic memory we can create arrays with dynamic capacity, so the number of slots inside can be varied on run-time. That way, you don't need to decide at coding the size of a particular array.
To generate that kind of dynamic array you will need to create a pointer referring to a space in memory.
int *array;
Once we have that connection between memory and a variable, we now need to set how much memory do we want(how many slots inside the array).
array = (int *)malloc(sizeof(int) * numberOfSlots);
This function malloc its provided by an external library called stdlib.h.
It will request the computer for a space in the memory. That space is defined inside those brackets (). There you set the number of bytes you want to request.
If what we want is an array of integers, we multiply the size of an integer with the slots we need.
To access or modify data inside an array, you can keep it simple by using [], like this:
array[0] = 1;
Important note: Never access or modify data inside an array without requesting memory before!
To read the numbers of chars in a line, you can simple use a loop, and read letter by letter until you find that '/n' character.
When using some library functions (e.g. strftime(), strcpy(), MultiByteToWideChar()) that deal with character arrays (instead of std::string's) one has 2 options:
use a fixed size array (e.g. char buffer[256];) which is obviously bad because of the string length limit
use new to allocate required size which is also bad when one wants to create a utility function like this:
char * fun(void)
{
char * array = new char[exact_required_size];
some_function(array);
return array;
}
because the user of such function has to delete the array.
And the 2nd option isn't even always possible if one can't know the exact array size/length before using the problematic function (when one can't predict how long a string the function will return).
The perfect way would be to use std::string since it has variable length and its destructor takes care of deallocating memory but many library functions just don't support std::string (whether they should is another question).
Ok, so what's the problem? Well - how should I use these functions? Use a fixed size array or use new and make the user of my function worry about deallocating memory? Or maybe there actually is a smooth solution I didn't think of?
You can use std::string's data() method to get a pointer to a character array with the same sequence of characters currently contained in the string object. The character pointer returned points to a constant, non-modifiable character array located somewhere in internal memory. You don't need to worry about deallocating the memory referenced by this pointer as the string object's destructor will do so automatically.
But as to your original question: depends on how you want the function to work. If you're modifying a character array that you create within the function, it sounds like you'll need to allocate memory on the heap and return a pointer to it. The user would have to deallocate the memory themselves - there are plenty of standard library functions that work this way.
Alternatively, you could force the user to pass in character pointer as a parameter, which would ensure they've already created the array and know that they will need to deallocate the memory themselves. That method is used even more often and is probably preferable.
I use valgrind to validate my code and it reports "Conditional jump or move depends on uninitialised value(s)" in one of my functions, which takes an array of pointers as argument.
Now, how do I check if an array contains junk values (might be using conditional break point) during run-time? Say, I don't access the pointer and hence the program doesn't break.
What is the condition to be checked for to identify a junk pointer?
While the other answers are correct, you can also get valgrind to help you identify which entry or entries in the array exactly are causing the problem.
What you need to do is to add code to your program which loops over the array (you may already have such a loop of course) and then include valgrind/memcheck.h and add something like this to the loop:
if (VALGRIND_CHECK_VALUE_IS_DEFINED(entry)) {
printf("index %d undefined\n", index);
}
where entry is the actual value from the array and index is the index of that value in the arry.
You can't differentiate a valid pointer and junk(uninitialized) pointer, they are all just numbers.
The fact that you are dealing with a "junk" pointer at some point in your code indicates, there's a problem before reaching that point.
You don't test for junk, you put non-junk values in the array at some point between the time you create the array, and the first time you consider using the values. Usually you do it when the array is created:
const char* strings[] = {0, "junk", "here"};
int some_values[10] = { 0 };
Valgrind uses its own tricks to identify what it thinks is junk, but those tricks are outside the scope of the standard, and regular C code can't use them (or anyway shouldn't try). Even if you could somehow hook into what valgrind does, you'd end up with code that doesn't work on all implementations, or that only works when run under valgrind.
You need to systematically initialize all your pointers to NULL.
When you deallocate memory reset your pointer to NULL as well.
This can be done using "constructor/destructor" functions wrapping malloc/free for instance.
Only then you can test for NULL valued pointer to see if something went wrong.
I asked a previous question about declaring an array in a for loop, e.g.
for(i=0;i<=1000;i++){
float arrayone[(length[i])];
do a bunch of other stuff
}
Basically, I'm trying to do an array whose length can be varied based on what step the program is on. I don't want to keep the array data saved permanently (like arrayone[][]), since it's big and there's lots of steps.
So I was told it's legal to declare the array only within this scope like this. But will it try to store 1000 copies of the array by the end, which I don't want? I'm a beginner, so I don't understand the nuances of what the blocks really do.
The alternative for me is just to make an array outside of the loop which has the maximum length ever needed, and to overwrite that at every step.
Edit: The use for the array is: I have a global array. The arrays in the loop are filled with function results using that global array, to save computing. The arrays get manipulated,...,...,and finally are used to change the global array. Then they're not needed anymore.
But will it try to store 1000 copies of the array by the end, which I don't want?
No, at the beginning of each iteration a new array will be allocated, and, since the array goes out of scope at the end of the iteration, at that time it will be deallocated, so only one array exists at one time.
That is the point of automatic variables (which that array is). At the end of the scope in which they are declared (usually but not always delimited by braces) they are automatically deallocated.
After each iteration of your loop is done all the variables that were declared inside your loop will be destroyed, including your array. So only one copy of your array will be kept.
That being said, however, you should know that initializing the array outside your loop is probably better, because you won't have to allocate memory on the stack every iteration.
If you were dynamically allocating your array (which you're not in your example) like this:
for(i=0;i<=1000;i++){
float * arrayone = (float*)malloc(i * sizeof(float));
}
then you have a problem. Here the local variable is the pointer, which when it gets destroyed you can no longer access the memory you allocated. This is the case where you would end up with 1000 different arrays in memory at once. You could free your memory before the pointer is destroyed, but I maintain that having the array declared outside the loop is still better.
How to know whether an array is initialized in C ? Functions like strlen() are not helping me as I dont want to know whether the array is empty or not.
There's no way to test that at runtime -- an uninitialized array looks just like one that has been initialized with garbage.
Depending on what you're doing, you need either to make sure the array is actually initialized or explicitly pass around a flag that tells you whether the values in the array are meaningful yet.
Also note that "whether the array is empty" is not a very meaningful concept in C. The array is just there, and it always contains whatever number of bits are necessary to represent the elements it's declared to have. Those bits may not have meaningful values, but the're always there.
You can't by using programmatic language features.
But you can by design and discipline. At declaration time set your array as a pointer to NULL.
Then make a function to assign both memory and value to your pointer and a corresponding freeing function to destroy it when is not needed anymore, setting it to NULL again. And then making every function that processes check for NULL as an error condition.
To do bounds recognition, set the last element to NULL.
Example:
char* myArray=NULL;
/* other code */
myArray = createMyArray(n_elements);
memset(myArray,0,sizeof(int)*n_elements); /* Set the allocated memory to zero */
/* other code */
myArray[0]=functionReturningAString();
myArray[n_elements-1]=functionReturningAnotherString();
/* other code */
/*Processing*/
char* incr=myArray;
while( incr != NULL){
processArray(incr);
incr++;/* Increments by size of char pointer to the next pointer*/
}
free_Array(&myArray);/* this function calls free() and sets myArray to NULL*/
This is usable, when you need a lot of efficiency. Otherwise you should either create your own arraylist or use an existing library which provides it.
You need too much discipline to keep track of every possible error condition, so it can be tiresome.
Usually is just better to just use a library which provides arraylist, linkedlist, HashSets, etc. For C I use a lot of Glib functions for this.