I have this structure in my code.
'Compilable' part of code:
#define MONITOR_TOPKEY HKEY_LOCAL_MACHINE
#define MONITOR_SUBKEY TEXT("SOFTWARE\\WMyRegistry")
struct params {
HKEY hMainKey;
LPTSTR hSubKey;
string path;
bool* runflg;
};
void _tmain(void) {
bool work = true;
string defaultPath = "HKEY_LOCAL_MACHINE";
defaultPath += "\\";
defaultPath += MONITOR_SUBKEY;
params* defaultParams = (params*) malloc(sizeof (params));
defaultParams->hMainKey = MONITOR_TOPKEY;
defaultParams->hSubKey = MONITOR_SUBKEY;
defaultParams->path = defaultPath; // HERE THERE IS A PROBLEM
defaultParams->runflg = &work;
}
When I set all parametrs (except "string") - all are good and working.
But when I try to inizialize 'string' parametr (or another type instead of this, for ex myClass type or another else type variable) I have the error
"Unhandled exception at 0x0FDEEAD0 (msvcr110d.dll) in ConsoleApplication1.exe:
0xC0000005: Access violation when writing to the address 0xCDCDCDCD."
I don't understand, why doens't work " defaultParams->path = defaultPath". Can someone explain?
I think there may be something wrong with malloc. Because malloc just allocate some memory for the object.
The string in your code may excess the boundary of the the memory you allocated. So there is access violation.
Try to use new instead of malloc.
You are using malloc on a struct with a C++ class std:string in it
malloc knows nothing about constructors so your string will not be initialized.
instead use new/delete and avoid using malloc/free in your C++ program
params* defaultParams = new params;
or preferably
std::unique_ptr<params> defaultParams(new params);
here you use a Registry class obj which initialize value second obj,
you can't initialize obj without using assignment operator overload.
first you should overload the assignment.
Related
While i try to debug
ERROR appear :
"Unhandled exception at 0x5784F2F6 (ucrtbased.dll) in Final project.exe: An invalid parameter was passed to a function that considers invalid parameters fatal."
Tried every thing can't figure out how to solve this.
using namespace std;
class Map :
{
private:
double *mhours_played;
string *maps;
unsigned element_num;
public:
Map()
{
maps[2] = { "Summoner's rift", "Aram" };
element_num = 2; mhours_played[2] = {};
}
~Map() { delete[] maps; }
};
These statements
maps[2] = { "Summoner's rift", "Aram" };
mhours_played[2] = {};
do not make sense. maps and mhours_played are pointers that within the body of the constructor have indeterminate values. They are not arrays as you think. For example the expression maps[2] is a scalar object of the type std::string.
Define the constructor at least like
Map() : mhours_played( new double[2]() ),
maps( new std::string[2] { "Summoner's rift", "Aram" } ),
element_num( 2 )
{
}
and the destructor like
~Map()
{
delete[] maps;
delete[] mhours_played;
}
It seems like the key misunderstanding here is the difference between stack and heap allocation. Your code would be (almost) correct if we were normally allocating space for an array in a function:
#include <string>
int main() {
std::string maps[2] = {"Chad", "Zimbabwe"};
}
This is perfectly valid, and works as expected. However, what you're trying to do is dynamically allocate space for an array of strings in memory location maps. This syntax for this would be as follows:
#include <string>
int main() {
std::string* maps;
maps = new std::string[2];
// ... more code ...
// always free your memory!
delete[] maps;
}
This tells the OS, "hey! I want some memory for an array, can I have some?" and the OS (hopefully) says "yeah, here you go have fun."
Currently, your code tries to access the second index in unallocated memory, and the OS really doesn't like that.
I hope this helps, and let me know if you need further clarification.
I have this struct:
struct event_ {
bool is_crossover = false;
bool is_birth = false;
bool is_repetitive = false;
int eID = 0;
bool inicio_fin = false;
fecha inicio_fecha;
fecha fin_fecha;
locacion inicio_l;
string eLatitud_i = 0;
string eLongitud_i = 0;
locacion fin_l;
string eLatitud_f = 0;
string eLongitud_f = 0;
personaje_info personajes_evento; //This is a class
int cantidad_personajes = 0;
string nombre;
string descripcion;
string tipo_evento;
event_ *sig, *ant;
};
And then, when I call the function:
event_ *n = new event_;
it sends me an Access Violation Error:
Exception thrown at 0x0F69F6E0 (ucrtbased.dll) in Auxiliar Libros.exe: 0xC0000005: Access violation reading location 0x00000000.
Anyone knows why is this happening?
As additional information, I ran a Code Metrics Analysis, and before this, the program worked perfectly fine. And also it tells me about exceptions, what should I do?
This code
string eLongitud_f = 0;
calls the string constructor with a NULL pointer (0 is another way of writing the NULL pointer), resulting in your access validation error.
What do you think that code is doing? Obviously 0 is an integer not a string. Did you mean this?
string eLongitud_f = "0";
Or did you mean this?
string eLongitud_f = "";
Maybe you even meant this
double eLongitud_f = 0.0;
You can also just have this
string eLongitud_f;
which is the same as the second alternative above. All these are possible, it's hard to know which you really want, but the fundamental problem is that you are have a string variable and you are trying to give it a value which is not a string.
To solve your problem, I think that the best thing to do is to reduce your code and try some combinaison.
First, you must try a little struct with only one bool variable to see if your new function is correct
struct event_
{
bool is_crossover = false;
};
event_ *n = new event_;
If your program continue to crash, your error is there, in new().
Else you can try then to reduce your structure removing what you think is correct.
Personnaly, I think that all your bool, int and event_ declaration are correct, so I remove them.
I think that similar object declaraction can also be removed and I remove them.
I have following structure:
struct event_
{
fecha fin_fecha;
locacion inicio_l;
string eLatitud_i = 0;
personaje_info personajes_evento;
};
What happens when you build and run this code ?
If you program has stopped to crash, the error is in removed code ?
Else, one (or more) declaration's line of this new structure is incorrect.
If changing your struct has too much impact in your code, your create a similar structure (other name not yet used) and you test it.
Please, can you try ? I think that you will find very quickly solve the problem yourself !
There are too much variables in your first code that can produce your crash ?
As an introduction, note that I am a Java programmer still getting used to the memory management issues in C++.
We have a base class which is used to encoded objects to a string of ASCII characters. Essentially, the class is using a stringstream class member to convert different datatypes to one long string, and then returns a char* to the caller which contains the encoded object data.
In testing for memory leaks, I am seeing that the implementation we are using seems prone to create memory leaks, because the user has to always remember to delete the return value of the method. Below is an excerpt of the relevant parts of the code:
char* Msg::encode()
{
// clear any data from the stringstream
clear();
if (!onEncode()) {
return 0;
}
// need to convert stringstream to char*
string encoded = data.str();
// need to copy the stringstream to a new char* because
// stringstream.str() goes out of scope when method ends
char* encoded_copy = copy(encoded);
return encoded_copy;
}
bool Msg::onEncode(void)
{
encodeNameValue(TAG(MsgTags::TAG_USERID), companyName);
encodeNameValue(TAG(MsgTags::TAG_DATE), date);
return true;
}
bool EZXMsg::encodeNameValue(string& name, int value)
{
if(empty(value))
{
return true;
}
// data is stringstream object
data << name << TAG_VALUE_SEPARATOR << value << TAG_VALUE_PAIRS_DELIMITER;
return true;
}
char* copy(string& source) {
char *a=new char[source.length() +1];
a[source.length()]=0;
memcpy(a,source.c_str(),source.length());
return a;
}
UPDATE
Well - I should have been more accurate about how the result of encode() is consumed. It is passed to boost:async_write, and program is crashing because I believe the string goes out of scope before async_write complete. It seems like I need to copy the returned string to a class member which is alive for life time of the class which sends the message (?).
This is the way the encode() method is actually used (after I changed the return value of to string):
void iserver_client::send(ezx::iserver::EZXMsg& msg) {
string encoded = msg.encode();
size_t bytes = encoded.length();
boost::asio::async_write(socket_, boost::asio::buffer(encoded, bytes), boost::bind(&iserver_client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
It looks like the proper way to do this is to maintain a queue/list/vector of the strings to async write. As noted here (and also in the boost chat_client sample). (But that is a separate issue.)
For this question:
in your copy function you return a pointer to a heap memory!So user maybe create memory leak,I think you can not use this copy function,you can do just like this in your encode func:
return data.str();
If you want to get a char*, you can use the member function of string:c_str(),
just like this:
string ss("hello world");
const char *p = ss.c_str();
If you use a stack string object you will not create memory leak,
You could just return a std::string. You have one there anyway:
string Msg::encode()
{
// clear any data from the stringstream
clear();
if (!onEncode()) {
return string{};
}
return data.str();
}
Then the caller would look like:
Msg msg;
msg.userID = 1234;
send(msg.encode().c_str());
The only way of achieving "automatic" deletion is with a stack variable (at some level) going out of scope. In fact, this is in general the only way of guaranteeing deletion even in case of an exception, for example.
As others mentioned std::string works just fine, since the char * is owned by the stack-allocated string, which will delete the char *.
This will not work in general, for example with non char * types.
RAII (Resource Acquisition is Initialization) is a useful idiom for dealing with such issues as memory management, lock acquisition/release, etc.
A good solution would be to use Boost's scoped_array as follows:
{
Msg msg;
msg.userID = 1234;
scoped_array<char> encoded(msg.encode());
send(encoded.get());
// delete[] automatically called on char *
}
scoped_ptr works similarly for non-array types.
FYI: You should have used delete[] encoded to match new char[source.length() +1]
While using a std::string works adequately for your specific problem, the general solution is to return a std::unique_ptr instead of a raw pointer.
std::unique_ptr<char[]> Msg::encode() {
:
return std::unique_ptr<char[]>(encoded_copy);
}
The user will then get a new unique_ptr when they call it:
auto encoded = msg.encode();
send(encoded.get());
and the memory will be freed automatically when encoded goes out of scope and is destroyed.
I have the following structure:
struct CountCarrier
{
int *CurrCount;
};
And this is what I want to do:
int main()
{
CountCarrier carrier = CountCarrier();
*(carrier.CurrCount) = 2; // initialize the *(carrier.CurrCount) to 2
IncreaseCount(&carrier); // should increase the *(carrier.CurrCount) to 3
}
void IncreaseCount(CountCarrier *countCarrier)
{
int *currCounts = countCarrier->CurrCount;
(*currCounts)++;
}
So, my intention is specified in the comments.
However, I couldn't get this to work. For starters, the program throws an exception at this line:
*(carrier.CurrCount) = 2;
And I suspect the following line won't work as well. Anything I did wrong?
struct CountCarrier
{
int *CurrCount; //No memory assigned
};
You need to allocate some valid memory to the pointer inside the structure to be able to put data in this.
Unless you do so, What you ar trying to do is attempting to write at some invalid address, which results in an Undefined Behavior, which luckiy in this case shows up as an exception.
Resolution:
struct CountCarrier
{
int *CurrCount; //No memory assigned
CountCarrier():CurrCount(new(int))
{
}
};
Suggestion:
Stay away from dynamic allocations as long as you can.
When you think of using pointers always think whether you really need one. In this case it doesn't really seem that you need one, A simple int member would be just fine.
You need to create the pointer. ie. carrier->CurrCount = new int;
*(carrier.CurrCount)
This is dereferencing the pointer carrier.CurrCount, but you never initialized it. I suspect this is what you want:
carrier.CurrCount = new int(2);
I seriously doubt that your program throws an exception at the line:
*(carrier.CurrCount) = 2;
While throwing an exception is certainly allowed behaviour, it seems much more likely that you encountered an access violation that caused the process to be killed by the operating system.
The problem is that you are using a pointer, but your pointer is not initialised to point at anything. This means that the result of the pointer dereference is undefined.
In this situation there does not seem to be any advantage to using a pointer at all. Your CurrCount member would work just as well if it was just a plain int.
If you are using C++, then you should encash its facilities. Instead of correcting your code, I am showing here that how the code should look like:
struct CountCarrier
{
int CurrCount; // simple data member
CountCarrier(int count) : CurrCount(count) {} // constructor
CountCarrier& operator ++ () // overloaded operator
{
++ CurrCount;
return *this;
}
};
We are overloading operator ++, because you have only one data member. You can replace with some named method also, like void IncrementCount().
CountCarrier carrier(2);
++ carrier;
As Als said, you need to provide some memory for the code to work.
But why make it so complicated? You don't need any pointers for the code you have to work. The "modern C++" way looks more like this:
struct CountCarrier
{
public:
CountCarrier(int currCount) : currCount(currCount) {}
void IncreaseCount() { ++currCount; }
int GetCount() const { return currCount; }
private:
int currCount;
};
int main()
{
CountCarrier carrier(2); // Initialize carrier.currCount to 2
carrier.IncreaseCount(); // Increment carrier.currCount to 3
}
Note how much cleaner and less error prone that is. Like I said, pick up a good introductory C++ book and read through it.
Class:
class myclass {
public:
myclass(void);
const char* server;
private:
char pidchar[6];
int pidnum;
};
The function
myclass parseINI(const char* file)
{
myclass iniOptions;
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile(file);
const char* server = ini.GetValue("", "server", "");
iniOptions.server = server;
std::cout << server << "\n"; // Prints the correct value here
fflush(stdout);
return iniOptions;
}
Calling it from the main function
int _tmain(int argc, TCHAR* argv[])
{
myclass options;
options = parseINI("myapp.ini");
std::cout << options.server << "\n"; // It prints junk here
return 0;
}
What did I do wrong?
The const char* returned by GetValue() probably belonged to the ini object. When you exited the parseIni() function, ini went out of scope and was destroyed, which could mean your pointer is no longer valid.
Try using a std::string for the server member type instead of const char*.
It looks like you are using memory that is released when CSimpleIniA goes out of scope in parseINI.
const char* server = ini.GetValue("", "server", "");
iniOptions.server = server;
Copy the value that is returned into a new memory block before you return from the parseINI function.
string server = ini.GetValue("", "server", "");
iniOptions.server = new char[server.length() + 1];
std::copy(server.begin(), server.end(), iniOptions.server);
iniOptions.server[server.length()] = 0;
const char* server = ini.GetValue("", "server", "");
This value is falling out of scope when the function terminates, so when you assign the value of that pointer to your object's server pointer, the place in memory they point to is having its memory freed off the stack at the end of the function, and it's then overtaken by other things.
Using a std::string or even just a char[] will be preferred to just fix the problem with the least amount of changes, as they will by assigned the actual value and not a location in memory like pointers.
What you really should do is look up referential transparency, though. That will prevent problems like this from occurring ever again
I's guess that the lifetime of the data pointed to by the char* returned from CSimpleIniA::GetValue() is the same as the CSimpleIni object itself. So when ini is destructed, the pointer returned from GetValue() becomes invalid. (I've never used CSimpleIni, and haven't looked at the docs carefully enough to know for sure, but that's what the behavior points to).
I'd suggest changing myclass::server to be a std:string object and set it using something like:
iniOptions.server = std::string(server);
which will give the myclass::server object it's own copy of the string data.
The way you are using class as a function returned data type in C++ is totally wrong.
In C++ there are 2 kinds of data type: value type, reference type.
class belongs to second one; From a function you can return a value type data or a pointer of any data.But you cann't retun a entity of a reference type. Because a entity of a reference type will be released right after the code reached out of the scope which the entity is defined.
You can do in either way:
1:
define parseINI as:
myclass* parseINI(const char* file)
{
myclass* iniOptions = new myclass();
........
return iniOptions;
}
and then use it like this:
myclass* options = parseINI("myapp.ini");
2:
define parseINI as:
void parseINI(myclass& options, const char* file)
{
........//asigne value to options's members
}
and then use it like this:
myclass options;
parseINI(options,"myapp.ini");
3:
Do what you did, but add a asignment method (operator=) to myclass
The problem is that the local variable server points to a character buffer returned by ini.GetValue(), which is destroyed when paraseINI() returns.
One way to fix this is to allocate a new buffer yourself and copy the characters.
const char* server = ini.GetValue("", "server", "");
int length = strlen(server) + 1; // length of the string +1 for the NULL character.
delete [] iniOptions.server; // free the old buffer
iniOptions.server = new char[length]; // allocate your own buffer
strncpy(iniOptions.server, server, length); // copy the characters
For this to work you have to make myclass::server non-const, and you have to initialize it to NULL in the constructor and delete it in the destructor.
A better way to deal with this situation would be use std::string instead of char * for muclass::server. This way std::string would take care of memory management for you, and the code would be exception-safe.
If you make muclass::server an std::string, then you simply do
const char* server = ini.GetValue("", "server", "");
iniOptions.server = std::string(server);
And you do not have to do anything with it in the constructor or the destructor.
iniOptions is located on the stack and disposed automatically when the function returns. You should allocate it on heap using new()