I've written a simple program returning the hostname of the IP address passed as an argument.
The program uses two functions: getaddrinfo() and getnameinfo().
I'm using Linux Mint, Netbeans IDE and the G++ compiler. The output is alright, there are no errors, but when I declare an
std::string str;
then cout gives no output, nothing is printed on the screen. However when I comment out the std::string declaration or remove it, the statement
std::cout << "hostname: " << hostname << std::endl;
prints the returned hostnames successfully.
What may be the cause of such a strange error?
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <iostream>
#include <string>
int main()
{
struct addrinfo* result;
struct addrinfo* res;
int error;
const char* host;
// When I comment out this line, cout prints the hostnames succesfully.
std::string str;
error = getaddrinfo("127.0.0.1", NULL, NULL, &result);
res = result;
while (res != NULL)
{
char* hostname;
error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, 1025, NULL, 0, 0);
std::cout << "hostname: " << hostname << std::endl;
res = res->ai_next;
}
freeaddrinfo(result);
// When I declare an std::string str variable, this cout doesn't either print anything
std::cout << "TEST" << std::endl;
return 0;
}
The arguments host and serv are pointers to caller-
allocated buffers (of size hostlen and servlen respectively) into which
getnameinfo() places null-terminated strings containing the host and
service names respectively.
http://man7.org/linux/man-pages/man3/getnameinfo.3.html
Your pointers must be actually allocated. The fact that commenting out that line changes anything is probably a coincidence or a strange side effect of optimization.
Thanks, it works now :). I'd like to find out when to use different ways to allocate memory.
As far as I know the main difference between creating an object in the following way:
// Creating objects:
Test t1;
Test* t2 = new Test();
The first object will be created in a heap and it will be automatically deleted when the function is finished running.
The second object will be created in a stack and memory deallocation has to be done manually using the delete/delete[] operators?
So what else should I keep in mind when dealing with pointers?
I guess I need to read a good book about computer architecture, as knowledge about memory and microprocessors will give profits :)
Related
I have currently a memory issue using the Botan library (version 2.15) for cryptography functions within a C++ project. My development environment is Solus Linux 4.1 (kernel-current), but I could observe this issue on Debian Buster too.
I observed that some memory allocated internally by Botan for calculations is not deallocated when going out of scope. When I called Botan::HashFunction, Botan::StreamCipher and Botan::scrypt multiple times, always going out of scope in between, the memory footprint increases steadily.
For example, consider this code:
#include <iostream>
#include <vector>
#include "botan/scrypt.h"
void pause() {
char ch;
std::cout << "Insert any key to proceed... ";
std::cin >> ch;
}
std::vector<uint8_t> get_scrypt_passhash(std::string const& password, std::string const& name) {
std::vector<uint8_t> key (32);
Botan::scrypt(key.data(), key.size(), password.c_str(), password.length(), salt.c_str(), salt.length(), 65536, 32, 1);
std::cout << "From function: before closing.\n";
pause();
return key;
}
int main(int argc, char *argv[]) {
std::cout << "Beginning test.\n";
pause();
auto pwhashed = get_scrypt_passhash(argv[1], argv[2]);
std::cout << "Test ended.\n";
pause();
}
I used the pause() function to observe the memory consumption (I called top/pmap and observed KSysGuard during the pause), when it is called from within get_scrypt_passhash before terminating, the used memory (both by top/pmap and KSysGuard) is about 2 MB more than at beginning, and after terminating the same.
I tried to dive into the Botan source code, but I cannot find memory leaks or the like. Valgrind also outputted that all allocated bytes have been freed, so no memory leaks were possible.
Just for information, I tried the same functionality with Crypto++ without observing this behavior.
Has anyone experienced the same issue? Is there a way to fix it?
I'm having a data abort exception in my code. It is very likely I am doing a very bad operation with chars. This code seems to work, but I wonder if it is actually invalid. The question is, what happens if you copy the data of one struct to another with char arrays involved. How is the data copied?
I have two functions, one which will purposefully leak, because I want to also know what happens if the struct created with new lives on purposefully, but the struct whose data it copied goes out of scope.
// Example program
#include <iostream>
#include <string>
#include "string.h"
typedef struct {
char name[12];
char stupid[12];
int hello;
} tFile;
void CopyFileAndDelete(tFile *file1){
tFile *file2 = new tFile;
*file2 = *file1;
std::cout << file2->name << std::endl;
delete file2;
}
void CopyFileAndLeak(tFile *file1){
tFile *file2 = new tFile;
*file2 = *file1;
std::cout << file2->name << std::endl;
}
int main()
{
tFile file1;
memset(&file1, 0, sizeof file1);
file1.hello = 22;
snprintf(file1.name, 12, "%s", "hellogoodfriendhwoareyou");
snprintf(file1.stupid, 12, "%s", "greate");
CopyFileAndDelete(&file1);
CopyFileAndLeak(&file1);
}
Other than this code being generally unsafe and more C than C++, it's correct (other than the leak.) There is no way this can produce an exception (unless new throws due to memory allocation failure.)
Arrays inside structs will be copied as you'd expect. The compiler will generally do a memcpy() to copy them (or a special memcpy-like built-in to optimize the copy operation.)
This isn't code you should write though. Use std::string instead. Don't use new and delete, use value types instead. If you really need to allocate, use unique_ptr or shared_ptr to do it.
Don't write code like this in C++ :-)
I am new to C++ and I've been learning how a program is executed. I am working on this code:
#include <iostream>
#include <string>
using namespace std;
void sayHello() {
cout << "Hello world!" << endl;
}
void greet(string name) {
cout << "Hello " << name << ", how are you?" << endl;
}
int main()
{
sayHello();
int a = 10;
string name = "Johan";
greet(name);
return 0;
}
I debugged this code in Code Blocks IDE. When it reached the return 0 statement, the yellow arrow (step into mode) returned to the string name statement and then it went to the return statement again to finish the debugging. I thought it is related to freeing memory, but why didn't it go to the int a = 10?
Is it normal? What did the debugger do? Shouldn't the debugger go to the closing bracket directly?
Thank you very much.
This is because std::string is a class with a non-default destructor, and this is your debugger's way of telling you that it's about to destroy this std::string object, by invoking its destructor. The debugger is saying, in so many words "ok, I'm doing the return statement now, and the first order of business is to destroy this std::string, so the execution jumps to the line which declared this std::string object, to let you know I'm about to execute this destructor; now, there, I've done it, now I'll resume the process of returning from this function".
A plain int doesn't have a fancy-shmancy destructor, and nothing special needs to be done, in order to make it go away.
I have the following simplified code at which while writing I thought was fine, but I have seem some random access violations.
Initially I thought as long as the arguments passed to async were on the stack, and not temporary variables, the code would be safe. I also thought that filename and extra data would destruct/considered not there at the brace where they leave scope.
It did some more research and read about the 'as if' principle that apparently compilers use for optimisation. I've often seen stack variables being optimised away in the debugger right after they have been used too.
My question here is basically, is it guaranteed that those stack variables will be around for the entire duration of the async function running. The .get() call on the future obviously synchronises the call before the two stack variables leave scope.
My current thinking is that it's not thread safe as the compiler can't see the variables being used after the call to the function, and therefore think it is safe to remove them. I can easily change the code to eliminate the problem (if there is one), but I really want to understand this.
The randomness of the AV, occurring more on some computers than others suggests it is a problem, and the scheduling order dictates whether this is a problem or not.
Any help is much appreciated.
#include <future>
#include <fstream>
#include <string>
#include <iostream>
int write_some_file(const char * const filename, int * extra_result)
{
std::ofstream fs;
try {
fs.open(filename);
} catch (std::ios_base::failure e) {
return 1;
}
fs << "Hello";
*extra_result = 1;
return 0;
}
int main(void)
{
std::string filename {"myffile.txt"};
int extraResult = 0;
auto result = std::async(std::launch::async, write_some_file, filename.c_str(), &extraResult);
// Do some other work
// ...
int returnCode = result.get();
std::cout << returnCode << std::endl;
std::cout << extraResult << std::endl;
return 0;
}
I am learning C++ and I am having quite a lot of trouble with my current assignment. I have completed a good amount of it so far. However I have been making very slow progress of late due to what I think is my poor understanding of what is going on behind the scenes.
What I am trying to do in the following code is:
Get two separate values (Bullet damage). Done.
Create a dynamic array. Done.
Fill a part (that is the size of a modulus of a random number between 1 and 10) of said dynamic array with one value and the rest with the other in a random order. Here I am having trouble.
Clean up the memory used by said dynamic array. Done.
The error I get is as follows:
Unhandled exception at 0x00a323e3 in Class 3.exe: 0xC0000005: Access
violation reading location 0xcdcdcdcd.
I'm pretty sure that the error occurs when I try to set ammoArray[i] to a value. But I don't know why it's giving it to me, my code compiles fine. I played around with it a bit and in one case I got it to store the memory addresses of bDamage and sDamage and then print out the memory addresses of each element of the array. What I want it to do is store the values held by bDamage and sDamage.
Now for my question:
Why won't ammoArray store the values of bDamage and sDamage instead of the memory addresses of the array's elements? And How do I get it to store them?
Here is my Main.cpp:
#include <cstdlib>
#include "Ammunition.h"
#include "AmmunitionManager.h"
#include "Bullet.h"
#include "Game.h"
#include "Pistol.h"
#include "Player.h"
#include "Point.h"
#include "Shell.h"
#include "Shotgun.h"
#include "WeaponManager.h"
#include "Weapons.h"
using namespace std;
void main()
{
Ammunition amVar;
AmmunitionManager *var = new AmmunitionManager();
amVar.setBDamage(6);
amVar.setSDamage(2);
var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
system("PAUSE");
}
Here is the .h file of the class in question:
#ifndef AMMUNITIONMANAGER_H
#define AMMUNITIONMANAGER_H
#include "Point.h"
#include "Ammunition.h"
class AmmunitionManager
{
public:
AmmunitionManager();
AmmunitionManager(int,int);
~AmmunitionManager();
void FillAmmoArray(int,int);
private:
Ammunition Ammo;
int **ammoArray;
};
#endif
Here is the .cpp file of the class in question:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "AmmunitionManager.h"
#include "Point.h"
#include "Ammunition.h"
using namespace std;
AmmunitionManager::AmmunitionManager()
{
}
AmmunitionManager::AmmunitionManager(int sDamage,int bDamage)
:Ammo(sDamage,bDamage)
{
cout << "Filling ammo reservoir." << endl;
ammoArray = new int* [10];
}
void AmmunitionManager::FillAmmoArray(int sDamage,int bDamage)
{
srand(time(NULL));
int *holdS = &sDamage;
int *holdB = &bDamage;
if(ammoArray)
{
for(int i = 0;i < 9;i++)
{
int randC = rand() % 2 + 1;
if(randC == 1)
{
cout << "Was: " << ammoArray[i] << endl;//I am getting the error here.
ammoArray[i] = holdS;
cout << "Is: " << ammoArray[i] << endl;
}
if(randC == 2)
{
cout << "Was: " << ammoArray[i] << endl;//I am getting the error here.
ammoArray[i] = holdB;
cout << "Is: " << ammoArray[i] << endl;
}
}
}
}
AmmunitionManager::~AmmunitionManager()
{
*ammoArray = 0;
if(ammoArray)
{
delete [] ammoArray;
}
}
Why won't ammoArray store the values of bDamage and sDamage instead of the memory addresses of the array's elements?
Because you said it should store addresses.
Here is a pointer to a pointer:
int **ammoArray;
and here is an array of pointers:
ammoArray = new int* [10];
And How do I get it to store them?
By doing this instead:
int *ammoArray;
and this:
ammoArray = new int [10];
and adjusting FillAmmoArray accordingly.
The default constructor should look like this:
AmmunitionManager::AmmunitionManager()
: ammoArray(nullptr)
{
}
The destructor should look like this:
AmmunitionManager::~AmmunitionManager()
{
delete [] ammoArray;
}
And you should only call srand once.
It's usually done at the beginning of main.
I'm not getting any errors (VS2013). But the values stored are the addresses of sDamage and bDamage.
Did you properly use AmmunitionManager(int sDamage,int bDamage) as a constructor for creating the AmmunitionManager object? From what I'm seeing, you're not.
Apart from that, may I ask why you're using exotic constructs such as **ammoArray instead of e.g. a simple vector<int>? I'm guessing it's part of your assignment, but I'm asking just to make sure I'm not missing anything.
I called the object like this:
int _tmain(int argc, _TCHAR* argv[])
{
AmmunitionManager* tc = new AmmunitionManager(5,10);
tc->FillAmmoArray(10,10);
return 0;
}
The problem is that you initialize AmmunitionManager with the default constructor:
AmmunitionManager *var = new AmmunitionManager();
In you default constructor you do nothing so ammoArray may contain any value.
It is better to initialize all the data to their default values:
AmmunitionManager::AmmunitionManager() : Ammo(), ammoArray(NULL/* or nullptr for C++11 */)
{
}
Now if you call for
var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
It will exit immediately since ammoArray is NULL.
Or probably you want to initialize ammoArray anyway, so the default constructor should have its initialization as well:
AmmunitionManager::AmmunitionManager() : Ammo()
{
ammoArray = new int* [10];
}
Also srand should be called only once, so better to place this code
srand(time(NULL));
in the main() or any other module which is guaranteed to be executed only once.
In the destructor, there is no need to zero *ammoArray=0, it actually puts 0 at the first element of that array (and that's it), you anyway delete it. And imagine that ammoArray is NULL, accessing *ammoArray would cause another segmentation fault.
Also there is no need to check for ammoArray beibg NULL before deleting it. The standard allows to 'delete' NULL pointers. delete will just return without doing nothing.
General note
It is better to use (safer and easier to maintain) std::vector instead of (dynamic) arrays and smart pointers instead of flat ones.
It's a bit tricky answering without building and debugging, but the first thing that strikes me are: Why are you using pointers (*) to int throughout?
Why don't you just have the array as a pointer:
int *ammoArray;
and make the other int-instances (remove the pointers - * and the address-of's (&))?
Regards