In the following code I get a warning with MSVC (C4996) that std::copy(errors.begin(),errors.end(),pErrors.get()); is not safe. It writes into the raw pointer. Is there an elegant and safe way to iterate over the elements?
The main goal is to prepare a built-in array for a call to a legacy function:
#include <iostream>
#include <initializer_list>
#include <memory>
#include <algorithm>
void print_errors_old_function(int argument_count,int* pErrors)
{
for (int i=0;i<argument_count;++i) { std::cerr << "Error" << pErrors[i] << " "; }
}
void print_errors(std::initializer_list<int> errors)
{
std::unique_ptr<int[]> pErrors{new int[errors.size()]};
std::copy(errors.begin(),errors.end(),pErrors.get()); // warning C4996
print_errors_old_function(errors.size(),pErrors.get());
}
int main()
{
print_errors({234,253,334});
return 0;
}
It seems a range based for loop is not possible with std::unique_ptr<int[]> and that regular for loop would arguably less readable than std::copy.
You don't need std::unique_ptr. std::vector will work fine, because &v[0] is guaranteed to give you a pointer to the internal buffer, and of course it also has a size() member function you can use to interface with C functions. Since C++11, there's also data(), which looks nicer than &v[0].
#include <iostream>
#include <initializer_list>
#include <vector>
void print_errors_old_function(int argument_count,int* pErrors)
{
for (int i=0;i<argument_count;++i) { std::cerr << "Error" << pErrors[i] << " "; }
}
void print_errors(std::initializer_list<int> errors)
{
std::vector<int> vErrors(errors);
print_errors_old_function(vErrors.size(), &vErrors[0] /* or vErrors.data() in C+11 */ );
}
int main()
{
print_errors({234,253,334});
return 0;
}
Notice how is also gets rid of the warning.
The other answer is correct, but note that were the function like this:
void print_errors_old_function(int argument_count,int* pErrors)
{
for (int i=0;i<argument_count;++i) { std::cerr << "Error" << pErrors[i] << " "; }
delete[] pErrors; // note this function effectively "consumes" the input
}
you wouldn't be able to use this approach, as there is no way to release ownership of the vector's memory. You'd have to make use std::unique_ptr the way you do in your question, but you'd have to use pErrors.release() instead of pErrors.get().
Visual C++ complains because on several functions which are defined in the standard, but it deems them as "unsafe", which makes standard-conforming code non-compilable. Sometimes, Microsoft provides workarounds, which are only available on Visual C++.
What you can do (choose one of these):
make use of the suggested Microsoft's workarounds
disable SDL checks (these checks turn these warnings into errors)
define _SCL_SECURE_NO_WARNINGS in your project. (to disable these warnings)
Related
so I thought adding unique to vector shouldn't work.
Why does it work for the below code?
Is it cause by not setting copy ctor as "deleted"??
#include <iostream>
#include <vector>
#include <memory>
class Test
{
public:
int i = 5;
};
int main()
{
std::vector<std::unique_ptr<Test>> tests;
tests.push_back(std::make_unique<Test>());
for (auto &test : tests)
{
std::cout << test->i << std::endl;
}
for (auto &test : tests)
{
std::cout << test->i << std::endl;
}
}
There is no copy here, only moves.
In this context, make_unique will produce an instance of unique pointer which is not named, and this push_back sees it as a r-value reference, which it can use as it wants.
It produce pretty much the same result than this code would:
std::vector<std::unique_ptr<Test>> tests;
auto ptr = std::make_unique<Test>();
tests.push_back(std::move(ptr));
This is called move semantics if you want to search more info on the matter. (and this only works from c++11 and beyond)
There are two overloads of std::vector::push_back according to https://en.cppreference.com/w/cpp/container/vector/push_back
In your case you will use the one with rvalue-ref so no copying required.
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
In c++11 standard we can declare variable in an unusual way. We can declare myVar as int(myVar); instead of int myVar. What is the point of this?
#include <iostream>
using namespace std;
int main() {
int(myVar);
myVar = 1000;
cout << myVar << endl;
return 0;
}
UPD Actually there is a certain reason why I asked this. What looked innocent just stopped to compile when we tried to port some code from MSVC C++03 to GCC C++11.
Here is an example
#include <iostream>
using namespace std;
struct MyAssert
{
MyAssert(bool)
{
}
};
#define ASSERT(cond) MyAssert(cond)
void func(void* ptr)
{
ASSERT(ptr); // error: declaration of ‘MyAssert ptr’
// shadows a parameter #define ASSERT(cond) MyAssert(cond)
}
int main()
{
func(nullptr);
return 0;
}
Sure. I can even do this:
int (main)()
{
}
Parentheses serve to group things in C and C++. They often do not carry additional meaning beyond grouping. Function calls/declarations/definitions are a bit special, but if you need convincing that we should not be allowed to omit them there, just look at Ruby, where parentheses are optional in function calls.
There is not necessarily a point to it. But sometimes being able to slap on some theoretically unnecessary parentheses helps make code easier to read. Not in your particular example, and not in mine, of course.
#include <typeinfo>
#include <iostream>
int main(void)
{
int *first_var[2];
int (*second_var)[2];
std::cout << typeid(first_var).name() << std::endl;
std::cout << typeid(second_var).name() << std::endl;
return 0;
}
Running this on my machine gives :
A2_Pi
PA2_i
The parenthesis in the declaration mostly serve the same purpose they do everywhere, group things that should be together regardless of the default priority order of the language.
Of course parenthesis with only one element inside is equivalent to just typing that element except in cases where parenthesis are mandatory (e.g function calls).
C++ does not break backward compatibility if it can help it.
The C that it was developed from had this syntax. So C++ inherited it.
A side effect of this backward compatibility are the vexing parse problems. They have not proved sufficiently vexing to justify breaking backward compatibility.
Suppose I have two overloaded functions :
fun1(int)
fun1()
In this case how can I use #pragma startup directive to start my program's execution with fun1(int) ?
The syntax only contains the function name :
#pragma startup fun1 100
Is there any way by which I can make a choice between these two functions?
UPDATE:
compiler- turbo c/c++ 3.1 (sorry for an old compiler )
It is a Borland specific directive, still documented as well. It just lets you specify a function that runs before the main() function is entered. You normally use it for an initialization function. It is a small band-aid for the infamous "static initialization order fiasco" that C and C++ implementations suffer from. Not so sure it stops the bleeding, having to pick the priority number ought to get impractical when the program gets large.
Anyhoo, nothing you ought to use as a replacement of main(). Although I'd suspect you could make it work as long as you don't return from the function and call exit(). You can't use an argument of course, there's nothing meaningful that the CRT can pass. So overloads can't work either. Stick with main().
#joey-rohan, I dont have borland but have tried to provide some code below to demonstrate:
#pragma start requires a non parameterised function, the number after the function call is the priority of the function where 0 is the highest and 255 the lowest. The function should ideally (varies in some compilers) be defined prior to the #pragma call. Source: embarcadero
I have done a bit of scouting about and think that the solution to your dilemma would be to use a mixture of #define and #pragma to achieve what you would like to do. For example something like:
#include <iostream>
#define myvalue 100
#define usemyvalue 0
void fun1(int passedInValue)
{
// carry out function here
std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
std::cout << "in fun1(void)\n";
std::cout << "Use my value = " << usemyvalue<< std::endl;
if (usemyvalue==1)
{
std::cout << "Using fun1(int) with a value!\n";
fun1((int)myvalue); // remember to cast as an int here
}
else
{
//normal fun1()code here
std::cout << "No var passed!\n";
std::cout << "Running standard non parametrised code!\n";
}
}
#pragma start fun1 10
int main()
{
std::cout << "Hello World\n";
return 0;
}
I know this is not as elegant as I would wish, therefore its probably not as elegant as you would like either, however it does allow for the functionality you need, with minimal modification. Unfortunately i only have GCC available to test against on this machine and it does not seem to support #pragma start it does however support a differing way of achieving the same (as shown on C Language Constructors and Destructors with GCC
so here is some code for GCC which I could test to let you see how to achieve what you are asking (because I would hate to pst a methodology that cannot be proven):
#include <iostream>
#define myvalue 100
#define usemyvalue 1 // this is the control switch to determine which to use,
// if the value is 1 then will pass a variable, otherwise will use
// the fun1(void) function
void fun1 (void) __attribute__((constructor));
void fun1(int passedInValue)
{
// carry out function here
std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
std::cout << "in fun1(void)\n";
std::cout << "Use my value = " << usemyvalue<< std::endl;
if (usemyvalue==1)
{
std::cout << "Using fun1(int) with a value!\n";
fun1((int)myvalue); // remember to cast as an int here
}
else
{
//normal fun1()code here
std::cout << "No var passed!\n";
std::cout << "Running standard non parametrised code!\n";
}
}
#pragma startup fun1
int main()
{
std::cout << "now running main function.\n";
std::cout << "Hello World\n";
return 0;
}
I suspect that the second method would also work with Borlands compiler but without access to it I cannot swear to that.
Hope this helps!
I can neither find any documentation on your compiler, nor use the compiler itself to check my guess. But from what I remember, #pragma startup takes function without arguments and returning void.
I would further guess that your code is not going to work if you leave only function taking int argument.
Disregarding that, I think it's not possible to pass an argument to function called in such a way.
As a solution I would propose you creating wrapper function, calling whatever function you would like with necessary arguments, like:
void start()
{
#pragma startup start
fun1( global_var_name );
}
I'm not exactly sure I understand the restrictions, but how about simply defining another function with a different name to forward to the function you want?
void fun2() { fun1(42); }
#pragma startup fun2 100
This question is a matter of style, since you can always write a for loop or something similar; however, is there a less obtrusive STL or BOOST equivalent to writing:
for (container<type>::iterator iter = cointainer.begin();
iter != cointainer.end();
iter++)
iter->func();
?
Something like (imagined) this:
call_for_each(container.begin(), container.end(), &Type::func);
I think it would be 1) less typing, 2) easier to read, 3) less changes if you decided to change base type/container type.
EDIT:
Thanks for your help, now, what if I wanted to pass some arguments to the member function?
#include <algorithm> // for_each
#include <functional> // bind
// ...
std::for_each(container.begin(), container.end(),
std::bind(&Type::func));
See std::for_each and std::bind documentation for details.
Missed your edit: Anyway here is another way of achieving what you want without using Boost, if ever need be:
std::for_each(foo_vector.begin(), foo_vector.end(),
std::bind(&Foo::func, std::placeholders::_1));
You can use std::for_each or boost's foreach constructs.
Use boost's BOOST_FOREACH or BOOST_REVERSE_FOREACH when you don't want to move the logic into another function.
I found out that boost bind seems to be well suited for the task, plus you can pass additional arguments to the method:
#include <iostream>
#include <functional>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
struct Foo {
Foo(int value) : value_(value) {
}
void func(int value) {
std::cout << "member = " << value_ << " argument = " << value << std::endl;
}
private:
int value_;
};
int main() {
std::vector<Foo> foo_vector;
for (int i = 0; i < 5; i++)
foo_vector.push_back(Foo(i));
std::for_each(foo_vector.begin(), foo_vector.end(),
boost::bind(&Foo::func, _1, 1));
}
Since C++11 standard the BOOST approach is standardized with different syntax as the "range-based-loop":
class Foo {
Foo(int x);
void foo();
}
vector<int> list = {Foo(1),Foo(2),Foo(3)};
for(auto &item: list) item.foo();
If you actually want to improve performance rather than just pretty up your code, what you really need is a map function. Eric Sink wrote a .net implementation