Remove the warning C6001 - c++

I am using VS2017 and do not understand why I am getting compiler "Warning C6001 Using uninitialized memory 'values'", on line if(values!= NULL) in catch block.
#include <windows.h>
typedef enum
{
VALUE_STATE_NOT_AVAILABLE = 1,
VALUE_STATE_ERROR = 2,
VALUE_STATE_VALID = 3,
VALUE_STATE_UNKNOWN = 4
} XyzValueState_t;
class XyzValue
{
private: XyzValueState_t _valueState;
protected: XyzValue( XyzValueState_t valueState ) {
_valueState = valueState;
}
}
typedef XyzValue* xyzValuePtr_t;
main(){
bool flag=true;
xyzValuePtr_t* values = NULL;
unsigned int _argument=2;
if(flag==true) {
values = new PCLValuePtr_t[2]{ NULL,NULL };
try {
values[0] = new PCLUnsignedInteger(_argument);
values[1] = new PCLUnsignedInteger(_argument);
xyz(values); // passing the value to third party function which returns void
}
catch(...) {
if(values!= NULL){
for(int k = 0; k < 1; k++) {
delete values[k];
values[k] = NULL;
}
delete [] values;
values = NULL;
}
}
}
}
Thank you in advance for your help and guidance

not quite sure why your compiler thinks this might be unitialized.
But, in C++, I'd argue that the way you're building your array with new is unnecessarily complicated and error prone. This look like someone from 1993 tried to write C++11. You have initializer lists, but you don't use RAII!
so, do the C++ thing and use C++'s deterministic object lifetime to manage memory. For an array of objects, this is elegantly handled by std::vector:
#include <vector>
class XyzValue;
main(){
bool flag=true;
unsigned int _argument=2;
if(flag==true) {
std::vector<XyzValue> values(2); // default initialization for two XyzValues.
try {
xyz(values.data()); // if you need the raw contiguous memory. **You probably don't.**
}
catch(...) {
// all the manual deletion not necessary anymore, because at end of scope, things are deconstructed automatically, so this catch clause now is empty.
}
}
}
See how this is much shorter, better readable, has the same functionality, but none of the need to manually delete anything? That's why we write C++ instead of C.

Related

std::unordered_map how to free struct created with malloc. Are 2 queries into the map required?

The following block of code seems to run fine
Generates:
Add 1000 things
_MyMap now holds [1000] things
_MyMap free'd and erased. size now [0]
#include <unordered_map>
#include <iostream>
typedef struct _entry
{
int now;
} ENTRY, * PENTRY;
std::unordered_map<int, PENTRY> _MyMap;
typedef std::unordered_map<int, PENTRY>::iterator itEntry;
int Now()
{
return 10;
}
main function, adding comments because the site won't let me just add code
int main()
{
PENTRY pE = NULL;
std::pair<itEntry, bool> r;
printf("Add 1000 things\n");
for (int i = 0; i < 1000; i++)
{
pE = (PENTRY)malloc(sizeof(ENTRY));
pE->now = Now();
r = _MyMap.insert(std::make_pair(i, pE));
if (false == r.second)
{
printf("For some crazy reason its already there\n");
continue;
}
}
// OK, theres probably 1000 things in there now
printf("_MyMap now holds [%u] things\n", _MyMap.size() );
// The following seems stupid, but I don't understand how to free the memory otherwise
for (int i = 0; i < 1000; i++)
{
// first query
auto it = _MyMap.find(i);
// if malloc failed on an attempt earlier this could be NULL right?
// I've had free impls crash when given NULL, so I check.
if (it != _MyMap.end() &&
NULL != it->second)
free(it->second);
// second query
_MyMap.erase(i);
}
printf("_MyMap free'd and erased. size now [%u]\n", _MyMap.size());
return 0;
}
Questions are inline in the comments
You probably want this:
auto it = _Map.find(idUser);
if (it != _Map.end())
{
free(it->second);
_Map.erase (it);
}
But it's really not a good idea to store a raw pointer in a collection this way. You should, ideally, just store the data directly in the map rather than storing a pointer to it. Otherwise, use std::unique_ptr so that the destruction of the pointer automatically frees the data.

Returning a string * type array from a function back into the main

I'm new to C++ and I am working on a function to shuffle strings
It takes an array of strings, shuffles them, and returns them back to the main.
I am returning a pointer to an array of strings called shuffled. The problem I have is that when I try to save that new pointer to the array to another pointer in the main, I start getting weird values that either reference to a file location in my computer or a bunch of numbers.
I'll post the entire code here but really what you want to look at is the return types, how I return it and how I save it in main. Please tell me why my pointer is not referencing the working array that is created in the function. Here's the code:
#include <cstdio>
#include <string>
#include <ctime>
#include <new>
#include <cstdlib>
using namespace std;
const char * getString(const char * theStrings[], unsigned int stringNum)
{
return theStrings[stringNum];
}
string * shuffleStrings(string theStrings[])
{
int sz = 0;
while(!theStrings[sz].empty())
{
sz++;
}
sz--;
int randList[sz];
for(int p = 0; p < sz; p++)
{
randList[p] = sz;
}
srand(time(0));//seed randomizer to current time in seconds
bool ordered = true;
while(ordered)
{
int countNumberInRandList = 0;//avoid having a sz-1 member list length (weird error I was getting)
for(int i = 0; i < sz; i++)
{
int count = 0;
int randNum = rand()%(sz+1);//get random mod-based on size
for(int u = 0; u < sz; u++)
{
if(randList[u] != randNum)
{
count++;
}
}
if(count == sz)
{
randList[i] = randNum;
countNumberInRandList++;
}
else
i--;
}
//check to see if order is same
int count2 = 0;
for(int p = 0; p < sz; p++)
{
if(randList[p] == p)
{
count2++;
}
}
if(count2 < sz-(sz/2) && countNumberInRandList == sz)
{
ordered = false;
}
}
string * shuffled[sz];
for(int r = 0; r < sz; r++) //getting random num, and str list pointer from passed in stringlist and setting that value at shuffled [ random ].
{
int randVal = randList[r];
string * strListPointer = &theStrings[r];
shuffled[randVal] = strListPointer;
}
for(int i = 0; i < sz; i++)
{
printf("element %d is %s\n", i, shuffled[i]->c_str());//correct values in a random order.
}
return *shuffled;
}
int main()
{
string theSt[] = {"a", "b", "pocahontas","cashee","rawr", "okc", "mexican", "alfredo"};
string * shuff = shuffleStrings(theSt);//if looped, you will get wrong values
return 0;
}
Strings allocate their own memory, no need to give them the "length" like you would have to do for char arrays. There are several issues with your code - without going into the details, here are a few working/non-working examples that will hopefully help you:
using std::string;
// Returns a string by value
string s1() {
return "hello"; // This implicitly creates a std::string
}
// Also returns a string by value
string s2() {
string s = "how are you";
return s;
}
// Returns a pointer to a string - the caller is responsible for deleting
string* s3() {
string* s = new string;
*s = "this is a string";
return s;
}
// Does not work - do not use!
string* this_does_not_work() {
string s = "i am another string";
// Here we are returning a pointer to a locally allocated string.
// The string will be destroyed when this function returns, and the
// pointer will point at some random memory, not a string!
// Do not do this!
return &s;
}
int main() {
string v1 = s1();
// ...do things with v1...
string v2 = s2();
// ...do things with v2...
string* v3 = s3();
// ...do things with v3...
// We now own v3 and have to deallocate it!
delete v3;
}
There are a bunch of things wrong here -- don't panic, this is what happens to most people when they are first wrapping their brains around pointers and arrays in C and C++. But it means it's hard to put a finger on a single error and say "this is it". So I'll point out a few things.
(But advance warning: You ask about the pointer being returned to main, your code does indeed do something wrong with that, and I am about to say a bunch of things about what's wrong and how to do better. But that is not actually responsible for the errors you're seeing.)
So, in shuffleStrings you're making an array of pointers-to-string (string * shuffled[]). You're asking shuffleStrings to return a single pointer-to-string (string *). Can you see that these don't match?
In C and C++, you can't actually pass arrays around and return them from functions. The behaviour you get when you try tends to be confusing to newcomers. You'll need to understand it at some point, but for now I'll just say: you shouldn't actually be making shuffleStrings try to return an array.
There are two better approaches. The first is to use not an array but a vector, a container type that exists in C++ but not in C. You can pass arrays around by value, and they will get copied as required. If you made shuffleStrings return a vector<string*> (and made the other necessary changes in shuffleStrings and main to use vectors instead of arrays), that could work.
vector<string *> shuffleStrings(...) {
// ... (set things up) ...
vector<string *> shuffled(sz);
// ... (fill shuffled appropriately) ...
return shuffled;
}
But that is liable to be inefficient, because your program is then having to copy a load of stuff around. (It mightn't be so bad in this case, because a smallish array of pointers isn't very large and because C++ compilers are sometimes able to figure out what you're doing in cases like this and avoid the copying; the details aren't important right now.)
The other approach is to make the array not in shuffleStrings but in main; to pass a pointer to that array (or to its first element, which turns out to be kinda equivalent) into shuffleStrings; and to make shuffleStrings then modify the contents of the array.
void shuffleStrings(string * shuffled[], ...) {
// ... (set things up) ...
// ... (fill shuffled appropriately) ...
}
int main(...) {
// ...
string * shuffled[sz];
shuffleStrings(shuffled, theSt);
// output strings (main is probably a neater place for this
// than shuffleStrings)
}
Having said all this, the problems that are causing your symptoms lie elsewhere, inside shuffleStrings -- after all, main in your code never actually uses the pointer it gets back from shuffleStrings.
So what's actually wrong? I haven't figured out exactly what your shuffling code is trying to do, but that is where I bet the problem lies. You are making this array of pointers-to-string, and then you are filling in some of its elements -- the ones corresponding to numbers in randList. But if the numbers in randList don't cover the full range of valid indices in shuffled, you will leave some of those pointers uninitialized, and they might point absolutely anywhere, and then asking for their c_strs could give you all kinds of nonsense. I expect that's where the problem lies.
Your problem has nothing to do with any of the stuff you are saying. As you are a beginner I would suggest not presuming that your code is correct. Instead I would suggest removing parts that are not believed to be problematic until you have nothing left but the problem.
If you do this, you should quickly discover that you are writing to invalid memory.
part two : you can't seem to decide on the type of what you are returning. Are you building a pointer to an array to return or are you returning an array of pointers.... you seem to switch between these intermittently.
part three : read #Gareth's answer, he explains about passing parameters around nicely for your instance.

Class type Segmentation Fault

It has been long time I did not use c++ and I have some basic errors. Can you tell me why I get Segmentation Fault from my generic code?
When I use int as a array type, it works perfectly but when I change it with "Trapdoor" type, it gives me Seg Fault.
array<array<int, colN>, rowN> SmartIds::createMatrix() {
array<array<int, colN> , rowN> a;
for(int i = 0; i < rowN; i++) {
a[i] = createTrapdoors();
}
//sort(a.begin(), a.end());
return a;
}
Below code generates seg fault
array<array<Trapdoor, colN>, rowN> SmartIds::createMatrix() {
array<array<Trapdoor, colN> , rowN> a;
for(int i = 0; i < rowN; i++) {
a[i] = createTrapdoors();
}
//sort(a.begin(), a.end());
return a;
}
I call my function like below;
auto i = createMatrix();
Trapdoor.cpp class
#include "Trapdoor.h"
#include <cryptopp/pwdbased.h>
using namespace std;
Trapdoor::Trapdoor() {
// TODO Auto-generated constructor stub
key = nullptr;
seed = nullptr;
iv = nullptr;
counter = 0;
}
Trapdoor::Trapdoor(byte* keyy, byte* ivv) {
key = keyy;
seed = keyy;
iv = ivv;
counter = 0;
}
Trapdoor::~Trapdoor() {
// TODO Auto-generated destructor stub
delete iv;
delete key;
delete seed;
}
void Trapdoor::deriveKeywithCounter() {
SecByteBlock derived(32);
PKCS5_PBKDF2_HMAC<SHA1> kdf;
//kdf.DeriveKey(derived.data(), derived.size(), 0, (byte*)b->data(), sizeof(b), NULL, 0, 100);
memset(iv, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH);
counter++;
}
int Trapdoor::getCounter() {
return counter;
}
The Trapdoor class does not have a correct copy-constructor or copy-assignment operator. So when objects are copied by value, the old and the new both have destructor called and pointers are freed twice etc. etc.
It's rarely a good design to have your class be calling delete on things that it did not new. Your code needs to be clear about who is responsible for freeing memory.
Usually, the best solution is to code Trapdoor so that it actually does not require any delete at all; then you do not have to write any special functions. See Rule of three/five/zero. (I will update this post to include a code sample if you show your class definition).

return pointers from function. Value not updated for one pointer

I have tried to obtain 2 pointers from a function and print it in main. the vague thing is one pointer seems to have recovered its values, while the other hasn't. And both the pointers, have the correct value inside the calling function, just before returning as well. Please tell me if you can identify any programmatic error that is preventing me from getting the right answer.
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
double* readctrls()
{
fstream inputs;
inputs.open("input_coods.txt");
int nol = 0,i = 0;
string line,temp,subtemptrans,subtemprots;
while(getline(inputs,line))
{
++nol;
}
// cout<<nol<<endl;
inputs.close();
inputs.open("input_coods.txt");
string *lines = new (nothrow) string[nol];
double* trans = new double[nol];
double* rots = new double[nol];
trans[0] =float(nol);
for(int i = 0; i<nol ; i++)
{
getline(inputs,lines[i]);
// cout<<lines[i]<<endl;
temp = lines[i];
// cout<<temp<<endl;
for(int j = 0; j<temp.length() ; j++)
{
if(temp.at(j) == ' ')
{
subtemptrans = temp.substr(0,j);
subtemprots = temp.substr(j+1,temp.length()-j);
// cout<<subtemprots<<endl;
*(trans+i+1) = ::atof(subtemptrans.c_str());
*(rots+i) = float(atoi(subtemprots.c_str()));
// cout<<rots[i]<<endl;
}
}
}
inputs.close();
// cout<<rots[2]<<endl;
return(rots,trans);
}
int main()
{
double *trans,*rots;
(rots,trans) = readctrls();
// cout<<sizeof(trans)<<endl;
for(int i=0;i<trans[0];i++)
{
cout<<*(trans+i)<<endl;
cout<<*(rots+i)<<endl;
}
}
The value of Trans is written fine in the memory and is perfectly retained from the main(). But the rots is giving garbage values of the order (e^-42). Please help me here.
C++ is neither Python nor Lua.
You can't return multiple values from a function.
return rots, trans;
This is the comma operator - evaluates its operands and yields the last (rightmost) one.
(rots, trans) = readctrls();
Likewise, this assigns to trans only, rots will be uninitialized.
Solution: you can either return a struct containing the two pointers, or pass them by reference, or whatever...
struct Foo {
double *rots;
double *trans;
};
Foo readctrls()
{
// ...
Foo r;
r.rots = rots;
r.trans = trans;
return r;
}
or:
void readctrls(double *&r, double *&t)
{
// ...
r = rots;
t = trans;
}
Other remarks:
Don't use raw arrays. std::vector<T> is generally preferred over T * in C++.
It's super wasteful to read the entire file just in order to count the lines, then read it once again to actually parse its contents. If you used an std::vector<double>, you could just vector.push_back(some_double); as you go along the lines, so you wouldn't have to walk through the file twice (you know, I/O is expensive, especially if the file is large).
You never delete the pointers that you allocate using new - here your program leaks memory.

error: request for member '..' in 'this', which is of non-class type '--* const'

My first ever question here. Please excuse me, I have just entered into C++ and was starting up with DS. STACK!!!
My code: I think
using namespace std;
typedef char stackElement;
class Stack
{
public:
stackElement *contents; //dynamically allocated: as we do not know what would be the size of our array.
int top, maxSize; // current Top index in the array
//max size of the array; we need it to know if the array is full
Stack(int maxSize)
{
contents = new stackElement(maxSize);
this.maxSize = maxSize;
if(contents == NULL)
{
cout<<"Insufficient memory";
exit(1);
}
top = -1;
}
~Stack()
{
delete [] contents;
contents = NULL;
maxSize = 0;
top = -1;
}
bool isEmpty()const
{
return top < 0;
}
bool isFull() const
{
return top == maxSize - 1;
}
void push(stackElement element)
{
if(isFull())
{
cout<<"STACK IS ALREADY FULL";
exit(1);
}
top = top + 1;
contents[top] = element;
}
};
int main()
{
cout<<"STACK IMPLEMENTATION";
int i = 1;
Stack s1(i);
s1.push('a');
s1.push('1');
return 0;
}
I am getting this error:
error: request for member 'maxSize' in 'this', which is of non-class type 'Stack* const'
If at all, you'd have to write this->maxSize = maxSize;, since this is a pointer.
But better not to write that at all and instead use the constructor-initializer list:
explicit Stack(int m)
: contents(new stackElement[m]), top(-1), maxSize(m)
{
// nothing else to do
}
I also added explicit so you don't accidentally convert 5 into a Stack.
You also wrote the array initialization wrong.
Also, you don't need to check that contents is not null: When new fails, it exits with an exception, it does not return a null pointer. (That behaviour would make no sense when you think in terms of objects.)
It is crucial to note that you have at most one naked new-expression in your constructor. Anything else is an exception-safety disaster, and a sign that you need to refactor and use single-responsibility resource-managing classes.
The destructor should just be: ~Stack() { delete [] contents; } Everything else is pointless waste.
Imagine you had to pay for every line of code you write. Be patient, lose the source, think.
Write
this->maxSize = maxSize;
instead of
this.maxSize = maxSize;
The this is a pointer type, not a reference type
this->maxSize instead of this.maxSize