How to modify a C++ structure with int * - c++

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.

Related

Problem while initializing attribute in constructor c++

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.

returning a 2D arrray in c++

I recentley started coding in C++ and I can't seem to understand how to ruturn the 2d array
GridArray
Is the problem somewhere in the type of the method because I can't seem to resolve it. Any help would be much appriciated!
static int GridArray [15][20];
int MapEditor::updateGrid(int *xCursor,int *yCursor){`
int width=16;
if(input.getInput()==psxUp){
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,255 );
(*yCursor)--;
if((*yCursor)<=0){
(*yCursor)=15;
}
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,224 );
}
if(input.getInput()==psxLeft){
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,255 );
(*xCursor)--;
if((*xCursor)<=0){
(*xCursor)=20;
}
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,224 );
}
if(input.getInput()==psxRight){
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,255 );
(*xCursor)++;
if((*xCursor)>=20){
(*xCursor)=0;
}
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,224 );
}
if(input.getInput()==psxDown){
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,255 );
(*yCursor)++;
if((*yCursor)>=15){
(*yCursor)=0;
}
VGA.drawRect((*xCursor)*16,(*yCursor)*16,(*xCursor)*16+width,(*yCursor)*16+width,224 );
}
if(input.getInput()==psxSqu){
spriteSelector.setSprite(bricks_destructive,bricks_destructive_palette);
spriteSelector.drawAtPosition((*xCursor)*16,(*yCursor)*16);
spriteSelector.update();
GridArray[(*yCursor)][(*xCursor)]=1;
Serial.println(GridArray[(*yCursor)][(*xCursor)]);
}
delay(120);
if(input.getInput()==psxSlct){
Serial.println(GridArray);
return GridArray;
}
}
In C++ you cannot return plain arrays (neither 1D ones nor 2D ones or higher). One could return a reference to such an array, and it would even be possible to encapsulate such arrays in a struct-object (which then could be returned).
However, these solutions are probably a work around of what is actually intended.
As you start coding C++ you might start with abandoning "old fashioned C style" and make use of the C++ concepts like standard library and its containers, e.g. with std::array. With that, you' code above example differently:
#include <array>
typedef std::array<std::array<int,15>,20> GridArray;
GridArray initGrid() {
GridArray ga = { { 0 } };
ga[0][0] = 15;
ga[0][1] = 30;
return ga;
}
int main() {
GridArray g = initGrid();
for(auto row : g) {
for (auto column : row) {
cout << column << " ";
}
cout << endl;
}
}
Note that there are other variants as well (e.g. passing arrays in as input parameters to functions which then alter them rather then creating and returning them in the function. But actually I think that the std::array-approach comes closest to that what you need.
I assume you are getting compile errors?
You have 2 problems:
The return type of your function is int but you are trying to return int
[15][20]
You aren't allowed to return an array from a function
Not all code paths return a value, your return GridArray needs to be outside the if statement.
you probably want something like this:
typedef int ArrayType[15][20];
static ArrayType GridArray;
ArrayType& f()
{
...
return GridArray;
}
Or even better use std::vector or std::array
Here is another solution, and it gets overlooked for more "technical" solutions, but this solution is rather simple.
This solution doesn't require intimate knowledge of pointers or references, doesn't require knowledge or usage of STL, doesn't require features or libraries that exist in standard C++ that may not exist on some platforms, should be very lightweight, and should be easily understandable by even beginner C++ programmers. However there is some code you would need to change to apply this technique.
The solution is this: simply wrap the 2-dimensional array inside a struct and pass / return the struct. That's it.
Since a struct is copyable and assignable (and arrays are neither one), then it is simply a matter of wrapping the array inside a struct and use that as a poor-man's container (even though it just works). Copies work, assignments work, passing to and from functions work, etc.
struct Array2D
{
int GridArray [15][20];
};
Then you simply pass and return Array2D's around. No pointers are necessary.
static Array2D theGrid;
Array2D& SomeFunction()
{
...
theGrid.GridArray[(*yCursor)][(*xCursor)]=1;
return theGrid;
}
The above returns a reference to the Array2D that was declared static. But you also get a choice of returning a copy of the results is so desired.
Array2D SomeFunction2()
{
...
theGrid.GridArray[(*yCursor)][(*xCursor)]=1;
return theGrid;
}
The above takes the static Array2D that was declared and returns a copy of it.
You then have the power to do things like:
Array2D tempGrid = theGrid; // get a copy of the original
//..
tempGrid.GridArray[0][0] = 1; // changes the copy but not the original
No need for for loops or memcpy's to assign one array to the other -- let the struct do that work automatically and easily for you since assignment and copy is built-in with structs and classes.
But again please note that you will need to change some code around to append xyz. to your current code that refers to GridArray, where xyz is the name of the Array2D instance.

C++ understanding RVO (as compared to returning local variable reference)

It's my first year of using C++ and learning on the way. I'm currently reading up on Return Value Optimizations (I use C++11 btw). E.g. here https://en.wikipedia.org/wiki/Return_value_optimization, and immediately these beginner examples with primitive types spring to mind:
int& func1()
{
int i = 1;
return i;
}
//error, 'i' was declared with automatic storage (in practice on the stack(?))
//and is undefined by the time function returns
...and this one:
int func1()
{
int i = 1;
return i;
}
//perfectly fine, 'i' is copied... (to previous stack frame... right?)
Now, I get to this and try to understand it in the light of the other two:
Simpleclass func1()
{
return Simpleclass();
}
What actually happens here? I know most compilers will optimise this, what I am asking is not 'if' but:
how the optimisation works (the accepted response)
does it interfere with storage duration: stack/heap (Old: Is it basically random whether I've copied from stack or created on heap and moved (passed the reference)? Does it depend on created object size?)
is it not better to use, say, explicit std::move?
You won't see any effect of RVO when returning ints.
However, when returning large objects like this:
struct Huge { ... };
Huge makeHuge() {
Huge h { x, y, x };
h.doSomething();
return h;
}
The following code...
auto h = makeHuge();
... after RVO would be implemented something like this (pseudo code) ...
h_storage = allocate_from_stack(sizeof(Huge));
makeHuge(addressof(h_storage));
auto& h = *properly_aligned(h_storage);
... and makeHuge would compile to something like this...
void makeHuge(Huge* h_storage) // in fact this address can be
// inferred from the stack pointer
// (or just 'known' when inlining).
{
phuge = operator (h_storage) new Huge(x, y, z);
phuge->doSomething();
}

Unhandled Exception: System.AccessViolationException : attempted to read or write protected

Problem: Getting an error when running my .exe
An unhandled exception of type 'System.AccessViolationException'
occurred in AddingWrapper.dll
Additional information: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
In the console it writes this:
Unhandled Exception: System.AccessViolationException : attempted to
read or write protected memory. This is often an indication that other
memory is corrupt. at gcroot (Add ^).. P$AAVAdd##(gcroot(Add^)) at
AddingWrapper.Adding(AddingWrapper, Int32* x, Int32* y)
Code snippet:
VB code:
Public Class Add
Public Function Adding(ByVal x As Double, ByVal y As Double) As Integer
Return x + y
End Function
End Class
AddingWrapper.h:
#pragma once
#include "stdafx.h"
class AddingWrapperPrivate;
class __declspec(dllexport) AddingWrapper {
private: AddingWrapperPrivate* _private;
public: AddingWrapper();
int Adding(int* x, int* y);
~AddingWrapper();
};
AddingWrapper.cpp
#include "stdafx.h"
#include "AddingWrapper.h"
#using "Class1.dll"
#include <msclr\auto_gcroot.h>
using namespace System::Runtime::InteropServices;
class AddingWrapperPrivate {
public: msclr::auto_gcroot<Add^> add;
};
AddingWrapper::AddingWrapper()
{
_private = new AddingWrapperPrivate();
_private->add = gcnew Add();
};
int AddingWrapper:: Adding(int* x, int* y) {
return _private->add->Adding(*x, *y);
};
AddingWrapper::~AddingWrapper()
{
delete _private;
};
calling code:
#include "stdafx.h"
#include "AddingWrapper.h"
#include <iostream>
int main()
{
int *a = 0;
int *b = 0;
AddingWrapper *add;
int results = add->Adding(a,b);
std::cout << "here is the result";
std::cout << results;
return 0;
}
Could it be due to my Class1.dll in AddingWrapper.cpp is using VB.net? Or it's a question of other issues? All the other threads seem to all differ in answer (i.e one is suggesting the user account doesn't have all the rights to the computer). If ever I missed on of those thread, please link it to me, this error is killing me
I should also add this error is at run time not compile time.
In the main function, you are using a "null" object pointer and passing in NULL pointers - that will cause the error you are seeing.
int main()
{
int a = 1;
// ^^^ remove the pointer (and give it a "interesting" value)
int b = 2;
// ^^^ remove the pointer
AddingWrapper add; // remove the pointer (or allocate with new)
// ^^^ remove the pointer
int results = add.Adding(&a, &b); // pass in the address of the integers
// ^^^ syntax change
std::cout << "here is the result";
std::cout << results;
return 0;
}
The variable a, b and add where only pointers, pointing to nothing; this causes access violations. Changing them to be automatic objects ("on the stack") will fix this. If dynamic objects are needed, you can new them (and delete them afterwards); but favour library utilities such as std::shared_ptr and std::unique_ptr etc. to help manage the lifetime of the object.
Several things:
You haven't shown your VB code. Since you've written an unmanaged class, not a managed one, it seems likely that either the import is not correct, or that you're passing a bad pointer.
Why are you passing an int* to the wrapper, only to dereference it right there? Why not pass an int?
You're in C++/CLI, why are you not writing a managed class? You wouldn't need auto_gcroot, and you don't need to deal with DLL imports/exports: VB.Net would be able to see your class the same as it can see any .Net class, and reference it just as easily as you can reference any .Net library.
Edit
OK, it wasn't obvious that you were trying to call some VB.Net code from C++. I thought you were trying to go the other direction.
The problem is almost certainly that you're passing a bad pointer to AddingWrapper::Adding.
You don't need to pass a pointer for basic data types, so you can get rid of that entire thing if you want. The fact that it's a double in VB but an int in C++ is fine, C++/CLI knows that the VB code takes a double and will convert appropriately.
Also, note that you're not passing a pointer between managed and unmanaged code. You're passing a pointer from one unmanaged class to another unmanaged class (whatever calls AddWrapper, to AddWrapper), but across the managed/unmanaged border, you're passing a plain old int.

Using member functions to deal with objects in the heap (c++)

I'm a beginner with C++, and this is a pretty basic syntax question, but i can't seem to find an answer elsewhere. Any input would be welcome. Here is a simplified version of the problem.
Say I have a class 'pair'
class pair
{
int a;
int b;
public:
pair(int x,int y)
{
a=x;
b=y;
}
int lookup()
{
return this->a+b;
}
};
Then i instanciate and copy that instance to a spot on the heap.
int func()
{
...
pair test(1,2);
pair *ptr=new pair;
*ptr=test;
}
Now here is the key. I don't destroy this memory allocation after the function ends. I want to use it later in this other function. The problem is, i would prefer to keep it in the heap and NOT have to copy it over to the stack(in the actual program it is very large). I would therefore like to do something like this:
int otherfunc()
{
...
int sum=*ptr.lookup;
}
but I get a compiler error. I end up having to do something like:
int otherfunc()
{
...
point temp=*ptr;
int sum=temp.lookup;
}
While this works, it is redundant, and when dealing with really large things it can even potentially cause an overflow. Anyone know the syntax for calling the method using the pointer while keeping it on the heap? Thanks.
I believe this is what you are trying to do:
int sum = ptr->lookup();
And as an aside, this:
return this->a+b;
Would probably be better as just this:
return a+b;
The expression *ptr.lookup will be interpreted as *(ptr.lookup), which is why you get the syntax error because ptr.lookup does not make sense. You'll need to tell the compiler dereference ptr first by using the parenthesis: (*ptr).lookup.
Because pointers are common in C (and C++), the (*a).b can be written in a simpler form: a->b.
Also, lookup is a function even if it does not take any parameters. You need to call it with ():
int sum=ptr->lookup();