This question already has answers here:
What happens when you call data() on a std::vector<bool>?
(4 answers)
Closed last year.
I required your help for a very strange behaviour that I can't understand.
I wrote a simple usage of vector.data :
void* ptr = NULL; // really initialized somewhere else
bool* boolPtr = NULL;
boolPtr = ((std::vector<bool>*)ptr)->data();
and when I compile (with -std=c++17) I got the error
void value not ignored as it ought to be
I try a lot a things but it seems that each time I call, from a casted vector (from void*), the data() method return a void instead of a bool*.
What did I miss ?
vector<bool> is not a proper vector. As weird as that sounds, that's the way it is. It can't give you a pointer to its internal bool array, because it doesn't have one, since it stores the values packed into single bits.
Related
This question already has answers here:
Returning an array using C
(8 answers)
Closed 6 months ago.
I wrote a simple c++ program where i am getting a simple float Array from a function. Then I call a function where the generated Array is a parameter of. I print the first value of the Array through the function. It works! BUT when i am declaring another array in the function before i print the value from the first array, the printed value is not the expected one. MAGIC!
CODE THAT DOESN'T WORK:
#include <iostream>;
float* getArray() {
float Array[] = { 4 };
return Array;
}
void compute(float* Array) {
bool newArray[1];
float content = Array[0]; //breakpoint: content will be -107374176.
std::cout << content;
}
int main() {
float* Array = getArray();
compute(Array);
}
OUTPUT: -1.07374e+08
When removing the line "bool newArray[1];" (line 10) the code starts to work.
OUTPUT: 4
Test it your self! Can someone explain me why this happens?
Your main function has a bug. It passes a pointer to Array to compute, which dereferences it. But Array is out of scope at this point since its scope ends when getArray ends. So you are trying to access an object that no longer exists. That is undefined behavior and produces completely unpredictable results.
Arguably, getArray also has a bug since it always returns a pointer to an object that no longer exists. So there is no way to use it. Whether or not that's a bug depends on what the caller is supposed to be able to do with the returned value which cannot be determined due to the lack of comments.
This question already has answers here:
C++ return value without return statement
(6 answers)
Closed 6 years ago.
I am confused with the following output in C++
int add()
{
int c = 2+3;
}
int main()
{
int x = add();
cout << x;
return 0;
}
This prints 5.even if we do not write return statement.
How this is managed in C++.
Please help.
This is UB. You're right to be confused - this can work one day and fail the next. Don't rely on undefined behavior.
If you want to know why it works, it's because parameters & return values are passed on a data structure called stack (well - usually; sometimes passed in the same register). Similarly, most implementations use this same stack for locals. Therefore, the int in add will be located in the same place as where the return value is expected (by your specific implementation) and your implementation doesn't invalidate memory when your int there is destructed. But it's still destructed, it's still UB and it might break in any second.
As the comments wrote, you might turn on warnings to avoid this kind of error.
This question already has answers here:
What is the function of an asterisk before a function name?
(4 answers)
Closed 6 years ago.
I am fairly new to C++ and I am trying to decode the piece of code shown below. In particular for the BaseSetAssoc::BlkType* line, I am not sure what the asterisk means in this case. I would appreciate some insight.
BaseSetAssoc::BlkType*
NMRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int master_id)
{
// Accesses are based on parent class, no need to do anything special
BlkType *blk = BaseSetAssoc::accessBlock(addr, is_secure, lat, master_id);
if (blk != NULL) {
// move this block to head of the MRU list
sets[blk->set].moveToHead(blk);
DPRINTF(CacheRepl, "set %x: moving blk %x (%s) to MRU\n",
blk->set, regenerateBlkAddr(blk->tag, blk->set),
is_secure ? "s" : "ns");
}
return blk;
}
BlkType isn't a member function, it's a type, possibly an enum or struct if not an inner class.
The BaseSetAssoc:: is needed to access such "inner" types (defined within a class, i.e. BaseSetAssoc).
So BaseSetAssoc::BlkType* is just a BaseSetAssoc::BlkType pointer.
It's not "following", it's "preceding". As the comments have said: it means that it is returning a pointer to BaseSetAssoc::BlkType, rather than a whole BaseSetAssoc::BlkType.
What does this mean? It means mostly that the pointer can be NULL, or non-existent. Before using the result of this function, it is almost mandatory that you check if it is NULL first.
This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 8 years ago.
I guess its a storage/definition difference but still I cant find a straight explanation of the behaviour. I have a function that returns a locally defined char* in two ways:
//Try 1:
char* printSomething()
{
char arr[100];
sprintf(arr, "The data %u", 100);
return arr;
}
//Try 2:
char* printSomething()
{
return "The data 100";
}
When I print the result of the first function It displays nothing (C) or garbage (C++) while on the second it prints the correct data.
I know I should store the data on the heap in cases like this or define static variable but still, how come the first doesnt work while the second does? and also, can I count on the second way to always work?
The first is just undefined behavior because arr is released when the function ends, so you're left with a dangling pointer.
The second works because "The data 100" is a string literal with static storage duration, which means it persists throught the lifetime of the program.
The implicit conversion to char* is deprecated though, and changing the contents will result in undefined behavior. I suggest you return const char* or std::string.
In both cases you returning char*
The first you return a pointer to a local array variable, located on the stack, which no longer exists after you exit the function. and may be rewritten.
In the second you returning pointer to a const string, located on the code segment, and it exist as long as the program is running.
This question already has answers here:
Pointer arithmetic when void has unknown size [closed]
(8 answers)
Closed 9 years ago.
I have some old code I inherited that I am maintaining and want to change as little as possible. It does not compile with newer compilers.
There is more to the code but basically the idea, I think, (regardless how bad) is to pass a void* to the start of a table of records of arbitrary record size. I do not want to make changes outside of this function since it gets ugly. I think I just want to cast to an unsigned char* and do the addition and then cast back to void* but I am having trouble figuring out the right casting etc.
Any suggestions?
Here is the original code:
foo(const void* recordArrayBasePtr ,ubin32 sizeOfStruct)
{
void * recordPtr;
int row = 9; //for example
recordPtr = const_cast<void *>( recordArrayBasePtr ) + sizeOfStruct * row;
}
You want to cast to char*, which is done with reinterpret_cast and not with const_cast. But considering that this is really C code, you can just as well use C-style casts which will be less of a hassle to write:
recordPtr = (void*)((char*)recordArrayBasePtr + sizeofStruct * row);