Multidimensional array of char pointer - c++

Good day to everyone,
there's some kind of big deal that I cannot figure out.
I create a multidimensional array of pointers:
char *listA[5000][2];
In particular condition, I want that specific strings are saved inside this array.
These are a normal string, in a simple variable, and another contained inside an array of strings.
listA[j][0]=strMix;
listA[j][1]=ingredients[i];
j++;
j, of course, is the row, that is increased for every adding.
The result must be an array that, for every row, contains two columns, one whit an ingredient, and another with the relative strMix.
The problem is that when I try to read this multidimensional array:
printf( "%s", listA[0][1]); // the ingredient
is always correct, but:
printf( "%s", listA[0][0]); // the strMix code
is always incorrect; precisely it reads the last strMix read, for every row.
I tried to change the order of the columns, and with my big surprise, the problem is always for the strMix, and never for the ingredients[i] string.
strMix column is correct only if I write it inside listA, and immediately read it. Of course, I'd say.
For example:
printf("Current: %s vs Previously: %s",lista[j][0], lista[j-1][0]);
they are the same, for every j, equal to the last strMix read.
If you have any ideas, something about memory or multidimensional array of pointers that I simply are missing, I'd appreciate your advises.
Thank you for the time, in every case.
fdt.

You're not saving strings in this array -- you're saving pointers.
This statement copies an address, not a string:
listA[j][0]=strMix;
If you want to copy the string, you can either:
Use an char array that stores the strings. For some strings, this may use too much memory. For others, it may offer not enough.
Use a char* array that stores addresses to the strings, and allocate separate memory for each referenced string.
Regardless, to copy the strings, prefer strncpy() to the unsafe strcpy().

Is it C or C++? Maybe instead of using the assignment:
listA[j][0]=strMix;
you should use strcpy function?
strcpy (listA[j][0], strMix);

Related

Should I always declare char array bigger than my string is?

So I know that you should declare char arrays to be one element bigger than the word you want to put there because of the \0 that has to be at the end, but what about char arrays that I don't want to use as words?
I'm currently writing a program in which i store an array of keyboard letters that have some function assigned to them. Should I still end this array with \0?
That is probably not necessary.
A null terminator is not a requirement for arrays of char; it is a requirement for "C-strings", things that you intend to use as unitary blobs of data, particularly if you intend to pass them to C API functions. It's the conventional way that the "length" of the string is determined.
But if you just want a collection of chars to use independently then knock yourself out.
We cannot see your code, but it sounds to me like you don't want or need it in this case.
The array should have, at least, the same number of elements as the data you will put there. So, if:
you don't need the '\0'
you won't place it there
you won't use routines that will depend on an '\0' to tell you the array size
... you are good with not using the trailing '\0'
If you're using C++, you should probably just use std::string or std::vector<char> or even std::array<char> and not worry about terminators.
It depends on usage. If you want to use it not as just byte array, but as c-string with probably usage of some standard string algorithms (strcmp and so on), or output to the stream - your array should ends with \0.
It depends on what you are trying to do, if you are trying to define a C-style string then, you need the terminator since the C-library won't be able to calculate the size of the string and other things if you don't...
In C++, though, the size of the string is already stored inside the std::string class along with the dynamic array of chars...
But if you just need a free container for storing characters where you don't need it to do C-string-like things... You are free to do:
char hello[128]; // 128 elements, do anything with them...
Without the terminator...
In your case, you are storing values, not creating a string, and you won't probably treat it as a string either, so doing it without the null-terminator, suffices...
\0 will certainly make it easier when wanting to use functions like strlen, strcmp, strcatand the like, but is not required.
An aside - We have an entire enterprise code base built upon strings (char arrays) with no null terminators in the database. Works just fine.

Want to know the length of a buffer C++

I am new to C++ and programming and I would like to know if there is a way to get the length of a pointer.
Let's say Myheader is a struct with different types of data inside.
My code goes like this:
char *pStartBuffer;
memcpy(pStartBuffer, &MyHeader, MyHeader.u32Size);
So I want to know the length of the buffer so that I can copy the data to a file using QT write function.
file.write(pStartBuffer, length(pStartBuffer));
How can I do this?
Pointers don't know its allocated size.
You may use std::vector which keep track of size for you:
std::vector<char> pStartBuffer(MyHeader.u32Size);
memcpy(pStartBuffer, &MyHeader, MyHeader.u32Size);
And latter:
file.write(pStartBuffer.data(), pStartBuffer.size());
There is no way to find the length of a buffer given nothing but a pointer. If you are certain that it's a string you can use one of the string length functions, or you can keep track of the length of the buffer yourself.
Pointer doesn't have a "length". What you need is the length of the array which the pointer points to.
No, you cannot extract that information from the pointer.
If the array contains a valid, null-terminated character string, then you can get the length of that string by iterating it until you find a null character which is what strlen does.
If not, then what you normally do is you store the length in a variable when you allocate the array. Which is one of the things that std::vector or std::string will do for you, whichever is more appropriate for your use.

How to read an array in a binary file in C++

Currently I read arrays in C++ with ifstream, read and reinterpret_cast by making a loop on values. Is it possible to load for example an unsigned int array from a binary file in one time without making a loop ?
Thank you very much
Yes, simply pass the address of the first element of the array, and the size of the array in bytes:
// Allocate, for example, 47 ints
std::vector<int> numbers(47);
// Read in as many ints as 'numbers' has room for.
inFile.read(&numbers[0], numbers.size()*sizeof(numbers[0]));
Note: I almost never use raw arrays. If I need a sequence that looks like an array, I use std::vector. If you must use an array, the syntax is very similar.
The ability to read and write binary images is non-portable. You may not be able to re-read the data on another machine, or even on the same machine with a different compiler. But, you have that problem already, with the solution that you are using now.

speed of handling input: growing an array, or counting input, allocating, and then reading

Basically I am wondering what would be a faster way of handling input from standard input:
Method one: Declaring an array of some arbitrary size, reading into the array, and if the input is more than the size, allocate a new array twice the size, copying the contents into the new array, and deallocating the previous array.
Method two: Read the whole input and count the number of lines while reading. reset the pointer back to the top of the input, declare an array of the length of the size of the number of lines, and then input into that array.
some background:
I'm not using vectors. please don't say to just use vectors...
they won't be typing the input, it'll be redirected from the command line to a file. akin to ./program < input.txt
I understand that the first method is more inefficient in terms of space, but is it faster than method two? if so, by how much? method 2 essentially takes 2n time to finish. I want to know if the first method would increase the runtime of my code.
Both methods are O(n). However, you're reading from stdin, so there's no way to rewind it back to the beginning unless something is already storing the data somewhere, so I don't see how you could use method 2.
You would need to use method 1. If you can use realloc, it might not even have to do any copying. If you're worried about the extra copying, you can store the items in a linked-list of buffers of exponentially increasing size, then create a single array at the end and copy each one only once.

Access Violation Using memcpy or Assignment to an Array in a Struct

Update 2:
Well I’ve refactored the work-around that I have into a separate function. This way, while it’s still not ideal (especially since I have to free outside the function the memory that is allocated inside the function), it does afford the ability to use it a little more generally. I’m still hoping for a more optimal and elegant solution…
Update:
Okay, so the reason for the problem has been established, but I’m still at a loss for a solution.
I am trying to figure out an (easy/effective) way to modify a few bytes of an array in a struct. My current work-around of dynamically allocating a buffer of equal size, copying the array, making the changes to the buffer, using the buffer in place of the array, then releasing the buffer seems excessive and less-than optimal. If I have to do it this way, I may as well just put two arrays in the struct and initialize them both to the same data, making the changes in the second. My goal is to reduce both the memory footprint (store just the differences between the original and modified arrays), and the amount of manual work (automatically patch the array).
Original post:
I wrote a program last night that worked just fine but when I refactored it today to make it more extensible, I ended up with a problem.
The original version had a hard-coded array of bytes. After some processing, some bytes were written into the array and then some more processing was done.
To avoid hard-coding the pattern, I put the array in a structure so that I could add some related data and create an array of them. However now, I cannot write to the array in the structure. Here’s a pseudo-code example:
main() {
char pattern[]="\x32\x33\x12\x13\xba\xbb";
PrintData(pattern);
pattern[2]='\x65';
PrintData(pattern);
}
That one works but this one does not:
struct ENTRY {
char* pattern;
int somenum;
};
main() {
ENTRY Entries[] = {
{"\x32\x33\x12\x13\xba\xbb\x9a\xbc", 44}
, {"\x12\x34\x56\x78", 555}
};
PrintData(Entries[0].pattern);
Entries[0].pattern[2]='\x65'; //0xC0000005 exception!!! :(
PrintData(Entries[0].pattern);
}
The second version causes an access violation exception on the assignment. I’m sure it’s because the second version allocates memory differently, but I’m starting to get a headache trying to figure out what’s what or how to get fix this. (I’m currently working around it by dynamically allocating a buffer of the same size as the pattern array, copying the pattern to the new buffer, making the changes to the buffer, using the buffer in the place of the pattern array, and then trying to remember to free the—temporary—buffer.)
(Specifically, the original version cast the pattern array—+offset—to a DWORD* and assigned a DWORD constant to it to overwrite the four target bytes. The new version cannot do that since the length of the source is unknown—may not be four bytes—so it uses memcpy instead. I’ve checked and re-checked and have made sure that the pointers to memcpy are correct, but I still get an access violation. I use memcpy instead of str(n)cpy because I am using plain chars (as an array of bytes), not Unicode chars and ignoring the null-terminator. Using an assignment as above causes the same problem.)
Any ideas?
It is illegal to attempt to modify string literals. Your
Entries[0].pattern[2]='\x65';
line attempts exactly that. In your second example you are not allocating any memory for the strings. Instead, you are making your pointers (in the struct objects) to point directly at string literals. And string literals are not modifiable.
This question gets asked several times every day. Read Why is this string reversal C code causing a segmentation fault? for more details.
The problem boils down to the fact that a char[] is not a char*, even if the char[] acts a lot like a char* in expressions.
Other answers have addressed the reason for the error: you're modifying a string literal which is not allowed.
This question is tagged C++ so the easy way to solve your problem is to use std::string.
struct ENTRY {
std::string pattern;
int somenum;
};
Based on your updates, your real problem is this: You want to know how to initialize the strings in your array of structs in such a way that they're editable. (The problem has nothing to do with what happens after the array of structs is created -- as you show with your example code, editing the strings is easy enough if they're initialized correctly.)
The following code sample shows how to do this:
// Allocate the memory for the strings, on the stack so they'll be editable, and
// initialize them:
char ptn1[] = "\x32\x33\x12\x13\xba\xbb\x9a\xbc";
char ptn2[] = "\x12\x34\x56\x78";
// Now, initialize the structs with their char* pointers pointing at the editable
// strings:
ENTRY Entries[] = {
{ptn1, 44}
, {ptn2, 555}
};
That should work fine. However, note that the memory for the strings is on the stack, and thus will go away if you leave the current scope. That's not a problem if Entries is on the stack too (as it is in this example), of course, since it will go away at the same time.
Some Q/A on this:
Q: Why can't we initialize the strings in the array-of-structs initialization? A: Because the strings themselves are not in the structs, and initializing the array only allocates the memory for the array itself, not for things it points to.
Q: Can we include the strings in the structs, then? A: No; the structs have to have a constant size, and the strings don't have constant size.
Q: This does save memory over having a string literal and then malloc'ing storage and copying the string literal into it, thus resulting in two copies of the string, right? A: Probably not. When you write
char pattern[] = "\x12\x34\x56\x78";
what happens is that that literal value gets embedded in your compiled code (just like a string literal, basically), and then when that line is executed, the memory is allocated on the stack and the value from the code is copied into that memory. So you end up with two copies regardless -- the non-editable version in the source code (which has to be there because it's where the initial value comes from), and the editable version elsewhere in memory. This is really mostly about what's simple in the source code, and a little bit about helping the compiler optimize the instructions it uses to do the copying.