Length of pointer to pointer - c++

I searched and I didn't find anything that is like my situation. I have a float** and well I know that it is a special type of pointer because it is an array of elements that have a float* that points to another zone of memory. So I write a simple code to detect the length of this matrix, to be more precise the length of the float + elements inside float**; But it results in a segmentation fault.
Here there is my code:
int Loader:: Length(float** length)
{
int count=0;
while(*length[count]!='\0'){
count++;
}
std::cout<<count<<std::endl;
return count;
}
Sorry for my english and sorry for the stupid question. Thanks to all.

I have a float** and well I know that it is a special type of pointer
Not really. A double pointer is just a special case of a single pointer. It is still a pointer to T, and that T happens to be float*.
because it is an array of elements
No! It is not an array. It may point to the first element of an array.
that have a float* that points to another zone of memory.
So, more precisely, a float** may point to the first element of an array full of float*. Where those individual float*s point to is another story.
So I write a simple code to detect the length of this matrix,
You cannot. When all you have is a pointer to the beginning of an array, then the size information is already lost.
That is, unless you have a convention for the last element, like C-style strings or string literals with their '\0' terminator. Which brings us to the next point...
int Loader:: Length(float** length)
{
int count=0;
while(*length[count]!='\0'){
Here's the culprit. Not all arrays are terminated by '\0'. In fact, it's not typical at all for arbitrary arrays containing a zero separator.
So unless the array to whose first element length points to actually contains an element which compares to '\0', then your loop will go one element past the end of the array and try to read from there. In that very moment, undefined behaviour is invoked and your program can do anything, including random crashes.
The best solution to your problem is to use std::vector, because a std::vector always knows its own size. So make it std::vector<float*>. Or better yet, a std::vector<std::vector<float>>.
In fact, if it's really a matrix, then make it std::vector<float>, store all contents contiguously, additionally store the matrix' width somewhere, and always calculate the offset for X/Y.

The problem is caused by your expectation that all arrays operate in the same way as literal character strings, ie that they are automatically terminated by a 0 value. Neither C++ or C work that way.
If you want the array length you need to do one of the following:
Pass the length along with the array everywhere.
Use a std::vector, std::deque or std::array instead of an array, and get the length from that.

Related

Is size of an array flexible in C++?

After declaring a character array, say char s[20], and eventually getting inputs using cin.getline(s,100) change the size of the array to 100, change (exactly) to the number of characters entered as input, or does it change at all? What happens to the array size that I initially declared?
I'm new to programming, so your simple explanation will be greatly appreciated. Thank you!
The size does not change what happens is that you are writing past the buffer size. If you write far enough through the buffer you will end up causing a buffer overflow.
You should use std::vector whenever you can instead of c-style arrays.
As Ted Lyngmo commented, in this case std::string will be better to use than std::vector or the c-style array:
std::string input;
std::getline(std::cin, input);
The answer is: No.
The size of the character array s doesn't changes to 100, but when you exceed the limit of the array's length, you cause a buffer overflow, which is really bad.
Let's consider an incorrect program, which is based on your assumption:
#include <iostream>
int main(void) {
char s[20];
std::cout << "Enter a sentence: ";
std::cin.getline(s, 100);
std::cout << s << std::endl;
return 0;
}
Here I just try to expand the size of array s, it actually doesn't.
If you enter an example sentence, like: hello-world-how-are-you-today (which contains 29 characters including a null-terminator), it'll just store:
hello-world-how-are-
And notice that it doesn't contains a null-terminator since all the containers are used and it just keeps reading which may cause undefined behavior (UB).
Arrays don't have dynamic memory. If you want dynamic memory allocation, you can use std::string for an array of characters, or std::vector.
std::string works like char s[x];, but it is more flexible and it has a few different things.
std::vector is basically like an array, but you can add / remove elements.
Syntax:
std::vector<type> name; // this is the classic syntax, I won't get more in-depth
Example:
std::vector<int> myVect;
You can add elements using myVect.insert(position, element); or something similar, I don't remember exactly, or you can use myVect.push_back(element); to add an element at the end of the vector.
Search it on cplusplus reference or GeeksForGeeks, you'll find a lot of information.
C++ doesn't have a variable-length array.
To handle this situation, you can have below data structures.
std::string
std::vector
dynamic array, using new[] in C++ or malloc() in C.
Click on the links, and you will find the description and usages.

Example of string literal bounding array new-expression first dimension argument

From cppreference:
In the following cases the expression specifying the first dimension is erroneous:
the value is smaller than the number of array elements provided in the brace-enclosed initializer (including the terminating \0 on a string literal).
Could someone provide an example for string literal being too long such that it bounds the first dimension of an array new-expression?
I don't seem to be able to come up with one :(
The only somewhat similar thing as I see is something like auto p1 = new char[1][5]{"xyz"}; but that isn't about the first dimension.
Something like this:
new const char[2]{"this is way more than one character"};
Note that gcc doesn't even compile new const char[2]{"x"}, but that's an orthogonal issue.
Could someone provide an example for string literal being too long such that it bounds the first dimension of an array new-expression?
Sorry but... if I understand correctly, the problem is the number of string literals, not the length of a single string literal
I mean: the problem is when you write something as
auto p = new char[1][10]{"abc", "123"};
In the case of a 2D array of char.
In case of a 1D array of char, see the Barry's answer.

(C/C++) Size of an array of chars

How to find out the lenght of an array of chars that is not null terminated/zero terminated or anything like that?
Because I wrote a writeFile function and I wanna get rid of that 'len' parameter.
int writeFile(FILE * handle, char * data, int len)
{
fseek(handle, 0, SEEK_SET);
for(int i=0; i <= len; i++)
fputc(data[i], handle);
}
You cannot get rid of the len parameter. The computer is not an oracle to guess your intentions. But you can use the fwrite() function which will write your data much more efficiently than fputc().
there is no portable way*, that is why sentinel values like null terminators are used.
In fact, its better to specify a length parameter, as it allows partial writes from data buffers (though in your case I would use a size_t/std::size_t for the length).
*you could try using _msize on windows, but it will lead to tears.
#define writeFile(handle, data) writeFileImpl(handle, data, sizeof data)
As Seith Carnegie commented and others answered, you cannot do that (getting the length of any array of char).
Some C libraries provide you with an extension giving an (over-sized) estimate of the length of heap-allocated memory (e.g. pointers obtained by malloc).
If you uses Boehm's garbage collector (which is very useful!), it gives you in <gc/gc.h> the GC_size function.
But when the array of char is inside a structure, or on the call stack, there is no way to get its size at runtime. Only your program knows it.
You can't get rid of the len parameter unless you have another way of determining the length of your data (usually by using a null terminator). This is because C and C++ don't store the length of the data. Furthermore, programmers might appreciate the len parameter. You don't always want to write out all the bytes in your array.

Character Pointers (allotted by new)

I wrote the following code:
char *pch=new char[12];
char *f=new char[42];
char *lab=new char[20];
char *mne=new char[10];
char *add=new char[10];
If initially I want these arrays to be null, can't I do this:
*lab="\0";
*mne="\0";
and so on.....
And after that if I want to add some cstring to an empty array can't I check:
if(strcmp(lab,"\0")==0)
//then add cstring by *lab="cstring";
And if I can't do any of these things, please tell me the right way to do it...
In C++11, an easy way to initialize arrays is by using brace-initializers:
char * p = new char[100] { 0 };
The reasoning here is that all the missing array elements will be zero-initialized. You can also use explicit value-initialization (I think that's even allowed in C++98/03), which is zero-initalization for the primitive types:
char * q = new char[110]();
First of all, as DeadMG says, the correct way of doing this is using std:string:
std::string lab; // empty initially, no further initialization needed
if (lab.size() == 0) // string empty, note, very fast, no character comparison
lab += "cstring"; // or even lab = "cstring", as lab is empty
Also, in your code, if you insist in using C strings, after the initialization, the correct checking for the empty string would be
if (*lab == '\0')
First of all, I agree with everybody else to use a std::string instead of character arrays the vast majority of the time. Link for help is here: C++ Strings Library
Now to directly answer your question as well:
*lab="\0";
*mne="\0";
and so on.....
This is wrong. Assuming your compiler doesn't give you an error, you're not assigning the "null terminator" to those arrays, you're trying to assign the pointer value of where the "\0" string is to the first few memory locations where the char* is pointing to! Remember, your variables are pointers, not strings. If you're trying to just put a null-character at the beginning, so that strlen or other C-string functions see an "empty" string, do this: *lab='\0'; The difference is that with single-ticks, it denotes the character \0 whereas with double, it's a string literal, which returns a pointer to the first element. I hope that made sense.
Now for your second, again, you can't just "assign" like that to C-style strings. You need to put each character into the array and terminate it correctly. Usually the easiest way is with sprintf:
sprintf(lab, "%s", "mystring");
This may not make much sense, especially as I'm not dereferencing the pointer, but I'll walk you through it. The first argument says to sprintf "output your characters to where this pointer is pointing." So it needs the raw pointer. The second is a format string, like printf uses. So I'm telling it to use the first argument as a string. And the 3rd is what I want in there, a pointer to another string. This example would also work with sprintf(lab, "mystring") as well.
If you want to get into C-style string processing, you need to read some examples. I'm afraid I don't even know where to look on the 'net for good examples of that, but I wish you good luck. I'd highly recommend that you check out the C++ strings library though, and the basic_string<> type there. That's typedef'd to just std::string, which is what you should use.

Assigning char value in one array to char value in another array

Sounds easy, but I've got a bug and I'm not sure what's causing it?
nopunccount = 0;
char *ra = new char[sizeof(npa)];
while (nopunccount <= strlen(npa)) {
ra[nopunccount] = npa[strlen(npa) - nopunccount];
nopunccount++;
}
ra never gets a value into it and I have verified that npa has char values to provide within the nopunccount range.
Any help is appreciated // :)
nopunccountstarts as 0, so in the first iteration of the loop the character assigned to ra[0] is npa[strlen(npa)]. This is the terminating '\0' of that string. So the resulting string in ra starts with a '\0' and is therefore considered to be ending at that first byte by the usual string functions.
What does the declaration of npa look like? If it is a pointer, sizeof(npa) will be the size of a pointer, rather than the allocated size. If these are zero-terminated strings (also known as "C strings"), then use strlen, not sizeof. If these aren't strings, you need to track how much you allocated in a separate variable.
I have some other critiques of this code, possibly unrelated to your problem.
while (nopunccount <= strlen(npa)) {
strlen is an O(n) operation. This code will traverse the string npa in every loop iteration. It's best to only compute the length once.
ra[nopunccount] = npa[strlen(npa) - nopunccount];
Same problem here.