int pointer allocates different memory in a heap; - c++

according to some exercise I have to define allocation is ascending or descending in stack and in a heap;
so when I print out the result in case of stack it is always 4 bytes in descending order but in a heap the difference is 32 in some case and after 848 why?
#include <iostream>
using namespace std;
int main(){
int a = 1;
int b = 1;
int c = 1;
int d = 1;
cout<<"Allocate in stack:"<<endl;
cout<<"adress a - "<<(uintptr_t)&a<<endl;
cout<<"adress b - "<<(uintptr_t)&b<<endl;
cout<<"adress c - "<<(uintptr_t)&c<<endl;
cout<<"adress d - "<<(uintptr_t)&d<<endl;
int* i = new int(1);
int* j = new int(1);
int* k = new int(1);
int* l = new int(1);
cout<<"Allocate in heap:"<<endl;
cout<<"adress i - "<<(uintptr_t)i<<endl;
cout<<"adress j - "<<(uintptr_t)j<<endl;
cout<<"adress k - "<<(uintptr_t)k<<endl;
cout<<"adress k - "<<(uintptr_t)l<<endl;
}
this are the a results:
Allocate in stack:
adress a - 622057224140
adress b - 622057224136
adress c - 622057224132
adress d - 622057224128
Allocate in heap:
adress i - 2426123523968
adress j - 2426123524000 // check this and successor the difference is 848
adress k - 2426123524848
adress k - 2426123524880

Related

C++ dynamic array allocation and strange use of memset

I recently ran into this code in C++:
int m=5;
int n=4;
int *realfoo = new int[m+n+3];
int *foo;
foo = realfoo + n + 1;
memset(realfoo, -1, (m+n+2)*sizeof(int));
Only the variable "foo" is used in the rest of the code, "realfoo" is never used (just freed at the very end).
I can't understand what that means.
What kind of operation is foo = realfoo + n + 1;? How is it possible to assign an array plus an int?
The memset sets every value of "realfoo" to -1. How does this affect "foo"?
EDIT
Since many have asked for the entire code. Here it is:
int Wu_Alg(char *A, char *B, int m, int n)
{
int *realfp = new int[m+n+3];
int *fp, p, delta;
fp = realfp + n + 1;
memset(realfp, -1, (m+n+2)*sizeof(int));
delta = n - m;
p = -1;
while(fp[delta] != n){
p=p+1;
for(int k = -p; k <= delta-1; k++){
fp[k]=snake(A, B, m, n, k, Max(fp[k-1]+1, fp[k+1]));
}
for(int k = delta+p; k >= delta+1; k--){
fp[k] = snake(A, B, m, n, k, Max(fp[k-1]+1, fp[k+1]));
}
fp[delta] = snake(A, B, m, n, delta, Max(fp[delta-1]+1, fp[delta+1]));
}
delete [] realfp;
return delta+2*p;
}
int snake(char *A, char *B, int m, int n, int k, int j)
{
int i=j-k;
while(i < m && j < n && A[i+1] == B[j+1]){
i++;
j++;
}
return j;
}
Source: http://par.cse.nsysu.edu.tw/~lcs/Wu%20Algorithm.php
The algorithm is: https://publications.mpi-cbg.de/Wu_1990_6334.pdf
This:
foo = realfoo + n + 1;
Assigns foo to point to element n + 1 of realfoo. Using array indexing / pointer arithmetic equivalency, it's the same as:
foo = &realfoo[n + 1];
memset is not setting the value to -1. It is used to every byte to -1
You should create a loop to iterate every element to assign correctly.
for(size_t i= 0; i< m+n+3; i++){
realfoo[i] = -1;
}
What kind of operation is foo = realfoo + n + 1;?
This is an assignment operation. The left hand operand, the variable foo, is assigned a new value. The right hand operand realfoo + n + 1 provides that value.
How is it possible to assign an array plus an int?
Because the array decays to a pointer.
The memset sets every value of "realfoo" to -1.
Not quite. All except the last value is set. The last one is left uninitialised.
Note that technically each byte is set to -1. If the system uses one's complement representation of signed integers, then the value of the resulting integer will not be -1 (it would be -16'843'009 assuming a 32 bit integer and 8 bit byte).
How does this affect "foo"?
foo itself is not affected. But foo points to an object that is affected.
Bonus advice: The example program leaks memory. I recommend avoiding owning bare pointers.

Intrusive values/addresses when crossing an dynamic allocated 2d array in c++

2D array initialization:
....
int main (...) {
....
double **hes = allocArray (2, 2);
// function (....) returning double
hes[0][0] = function (3, &_X, &_Y, _usrvar_a, _usrvar_b);
hes[0][1] = function (4, &_X, &_Y, _usrvar_a, _usrvar_b);
hes[1][0] = function (4, &_X, &_Y, _usrvar_a, _usrvar_b);
hes[1][1] = function (5, &_X, &_Y, _usrvar_a, _usrvar_b);
....
return 0;
}
double **allocArray (int row, int col) {
double **ptr = new double*[row];
for (int i = 0; i < row; i++)
{
ptr[i] = new double[col];
}
return ptr;
}
Values of 2d double type array is:
12 2
2 14
I know that because I have crossed it with iterators (i, j)
void otherFunc (double **h, ....) {
....
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
std::cout << " " << h[i][j];
....
}
Output is
12 2 2 14
(I do not need to separate the rows of 2D array in output, do not write about that)
I want to cross it with pointer:
void otherFunc (double **h, ....) {
....
for (double *ptr = h[0]; ptr <= &h[1][1]; ptr++)
std::cout << " " << *ptr;
....
}
Output is:
12 2 0 1.63042e-322 2 14
Why 0 and 1.63042e-322 appeared here?
h[0] and h[1] in your run are not one just after the other:
h[1] in your specific run happens to be four numbers after h[0].
This behavior probably is random meaning that (as far as we know from your question) probably you didn't explicitly specify the relative positions of h[0] and h[1]. If this is the case the next time you run your code h[1] could even be smaller than h[0] this results in undefined behavior.
What you probably want is something of this kind: allocate four doubles and assign the address of the first to a pointer double* hh = malloc(4 * sizeof(double)); And then for the variable h which is a pointer to pointer double* h[2]; you want to assign the pointers as follows:
h[0] = hh;
h[1] = hh+2;
of course there are safer ways to do this. But this could be a good start.

Memory reallocation causes segmentation fault on loop

What I'm doing here is basically joining to a global array (optimisedMesh) some smaller arrays (Bx, By, and Bz). As you can see the content and size of Bx, By and Bz is set on the b and c loops. Once they are fully defined they are joined to optimisedMesh.
This process should happen every "a" for loop.
I've found two problems trying this. The first one is that when I call free(Bx); once I've finished needing this array, the debugger returns me a segmentation fault, I'm not sure why.
The second one happens on the second loop of the "a" for loop. On the first loop
the realloc seems to work fine, but on the second it returns the 0x0 address, which causes a segmentation fault further in the code.
Also, I've ommited the By and Bz code because it looks exactly the same as Bx.
Thanks for your time.
int* LBxIA = (int*) calloc (1,sizeof(int*)); int* LBxIB = (int*) calloc (1,sizeof(int*)); int* LByIA = (int*) calloc (1,sizeof(int*)); int* LByIB = (int*) calloc (1,sizeof(int*)); int* LBzIA = (int*) calloc (1,sizeof(int*)); int* LBzIB = (int*) calloc (1,sizeof(int*));
int* LBxFA = (int*) calloc (1,sizeof(int*)); int* LBxFB = (int*) calloc (1,sizeof(int*)); int* LByFA = (int*) calloc (1,sizeof(int*)); int* LByFB = (int*) calloc (1,sizeof(int*)); int* LBzFA = (int*) calloc (1,sizeof(int*)); int* LBzFB = (int*) calloc (1,sizeof(int*));
Quad** Bx = (Quad**) calloc(1,sizeof(Quad*));
int maxSize = Math::maxof(xLenght,yLenght,zLenght);
for(int a = 0; a < maxSize; a++){
int BxCount = 0; int ByCount = 0; int BzCount = 0;
Bx = (Quad**) realloc(Bx,sizeof(Quad*));
for(int b = 0; b < maxSize; b++){
for(int c = 0; c < maxSize; c++){
//Bx
if(a <xLenght && b < yLenght && c < zLenght){
if(cubes[a][b][c] != nullptr){
if(!cubes[a][b][c]->faces[FACE_LEFT].hidden){
if(!LBxIA){
LBxIA = new int(c);
}else{
LBxFA = new int(c);
}
}else{
if(LBxIA && LBxFA){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount - 1] = new Quad(Vector3(a,b,*LBxIA),Vector3(a,b,*LBxFA),Vector3(a,b+1,*LBxIA),Vector3(a,b+1,*LBxFA));
LBxIA = nullptr;
LBxFA = nullptr;
}
}
}else{
if(LBxIA && LBxFA){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount-1] = new Quad(Vector3(a,b,*LBxIA),Vector3(a,b,*LBxFA),Vector3(a,b+1,*LBxIA),Vector3(a,b+1,*LBxFA));
LBxIA = nullptr;
LBxFA = nullptr;
}
if(LBxIB && LBxFB){
BxCount++;
Bx = (Quad**) realloc(Bx, BxCount * sizeof(Quad*));
Bx[BxCount-1] = new Quad(Vector3(a+1,b,*LBxIB),Vector3(a+1,b,*LBxFB),Vector3(a+1,b+1,*LBxIB),Vector3(a+1,b+1,*LBxFB));
LBxIB = nullptr;
LBxFB = nullptr;
}
}
}
}
}
optimisedMeshCount += (BxCount + ByCount + BzCount)*sizeof(Quad*);
optimisedMesh = (Quad**) realloc(optimisedMesh, optimisedMeshCount);
copy(Bx, Bx + BxCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)));
copy(By, By + ByCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)) + BxCount*sizeof(Quad*));//TODO AquĆ­ error
copy(Bz, Bz + BzCount*sizeof(Quad*), optimisedMesh + (optimisedMeshCount - (BxCount + ByCount + BzCount)*sizeof(Quad*)) + BxCount*sizeof(Quad*) + ByCount*sizeof(Quad*));
free(Bx);
}
I guess, the problem is with the three copy lines.
copy expects begin and end of some container or memory range. In your case you provide Bx, which is fine, and Bx + BxCount*sizeof(Quad*), which is way beyond the end of Bx memory.
This is because Bx + 1 is not Bx + 1 byte, but &Bx[1], which is the second element. Equally, Bx + BxCount would be the "end" as expected by copy.
This means Bx + BxCount*sizeof(Quad*) is, on a 64 bit system, eight times as much beyond the end of Bx memory range. Same goes for optimisedMesh, By and Bz. As a consequence, you copy too many elements and as a result get memory corruption.
Using std::vector and storing Quads instead of pointers to Quad
std::vector<Quad> Bx, By, Bz, optimisedMesh;
for (int a = 0; a < maxSize; a++) {
Bx.clear();
for (int b = 0; b < maxSize; b++) {
for (int c = 0; c < maxSize; c++) {
// ...
Quad qx(Vector3(a,b,*LBxIA),
Vector3(a,b,*LBxFA),
Vector3(a,b+1,*LBxIA),
Vector3(a,b+1,*LBxFA));
Bx.push_back(qx);
// ...
}
}
std::copy(Bx.begin(), Bx.end(), std::back_inserter(optimizedMesh));
std::copy(By.begin(), By.end(), std::back_inserter(optimizedMesh));
std::copy(Bz.begin(), Bz.end(), std::back_inserter(optimizedMesh));
}
As you can see, no explicit allocation, reallocation or freeing of memory, no counting of elements.
Unrelated, but you must also pay attention to LBxIA = new int(c); and LBxIA = nullptr;, which leaks memory.

Pass arrays between VB.NET and VC++

I've a written a function to calculate the correlation matrix for variables (risks) held in a flat file structure. I.e. RiskID | Year | Amount
I have written the function because the library routines that I can find necessitate a matrix input. That is, RiskID as 2nd dimension and year as the 1st dimension - with amounts as actual array values. The matrix needs to be complete, in that zero values must be included also and hence for sparsely populated non zero data - this leads to wasted iterations which can be bypassed. The routine relies upon the data being sorted first by Year (asc) then by RiskID (asc)
I have written the routine in C++ (for speed) to be compiled as a dll and referenced in VB.NET. I need to pass 3 arrays (one each for each of the headers) and return a 2 dimensional array back to VB.NET. I guess I'm cheating by passing 3 individual 1d arrays instead of a 2d array but there you go. I'll post the full C++ routine as others may find it useful if seeking to do something similar. I'd be surprised if this hasn't been done before - but I just can't find it.
I lack the interop knowledge to implement this properly and am getting nowhere googling around. As far as I can workout I may need to use SAFEARRAY ?
Or is there a quick fix to this problem? Or is SAFEARRAY a piece of cake. Either way an example would be very helpful.
Also, as a side note - I'm sure the memory management is failing somewhere?
Here is the Visual C++ (VS2013)
Header File
#ifndef CorrelLib_EXPORTS
#define CorrelLib_API __declspec(dllexport)
#else
#define CorrelLib_API __declspec(dllimport)
#endif
// Returns correlation matrix for values in flat file
extern "C" CorrelLib_API double** __stdcall CalcMatrix(int* Risk, int* Year, double* Loss, const int& RowNo, const int& RiskNo, const int& NoSimYear);
CPP File
#include "stdafx.h"
#include "CorrelLib.h"
#include <memory>
#include <ctime>
using namespace std;
extern "C" CorrelLib_API double** __stdcall CalcMatrix(int* Risk, int* Year, double* Loss, const int& RowNo, const int& RiskNo, const int& NoSimYear)
{
int a, b;
int i, j, k;
int YearCount, MissingYears;
int RowTrack;
//Relies on Year and Risk being sorted in ascending order in those respective orders Year asc, Risk asc
double *RiskTrack = new double[RiskNo](); //array of pointers?
int *RiskTrackBool = new int[RiskNo](); //() sets inital values to zero
double *RiskAvg = new double[RiskNo]();
double *RiskSD = new double[RiskNo]();
//Create 2d array to hold results 'array of pointers to 1D arrays of doubles'
double** Res = new double*[RiskNo];
for (i = 0; i < RiskNo; ++i)
{
Res[i] = new double[RiskNo](); //()sets initial values to zero
}
//calculate average
for (i = 0; i < RowNo; i++)
{
a = Risk[i];
RiskAvg[a] = RiskAvg[a] + Loss[i];
}
for (i = 0; i < RiskNo; i++)
{
RiskAvg[i] = RiskAvg[i] / NoSimYear;
}
//Enter Main Loop
YearCount = 0;
i = 0; //start at first row
do {
YearCount = YearCount + 1;
a = Risk[i];
RiskTrack[a] = Loss[i] - RiskAvg[a];
RiskTrackBool[a] = 1;
j = i + 1;
do
{
if (Year[j] != Year[i])
{
break;
}
b = (int)Risk[j];
RiskTrack[b] = Loss[j] - RiskAvg[b];
RiskTrackBool[b] = 1;
j = j + 1;
} while (j < RowNo);
RowTrack = j;
//check through RiskTrack and if no entry set to 0 - avg
for (j = 0; j < RiskNo; j++)
{
if (RiskTrackBool[j] == 0)
{
RiskTrack[j] = -1.0 * RiskAvg[j];
RiskTrackBool[j] = 1;
}
}
//Now loop through and perform calcs
for (j = 0; j < RiskNo; j++)
{
//SD
RiskSD[j] = RiskSD[j] + RiskTrack[j] * RiskTrack[j];
//Covar
for (k = j + 1; k < RiskNo; k++)
{
Res[j][k] = Res[j][k] + RiskTrack[j] * RiskTrack[k];
}
}
//Reset RiskTrack
for (k = 0; k<RiskNo; k++)
{
RiskTrack[k] = 0.0;
RiskTrackBool[k] = 0;
}
i = RowTrack;
} while (i < RowNo);
//Account For Missing Years
MissingYears = NoSimYear - YearCount;
for (i = 0; i < RiskNo; i++)
{
//SD
RiskSD[i] = RiskSD[i] + MissingYears * RiskAvg[i] * RiskAvg[i];
//Covar
for (j = i + 1; j < RiskNo; j++)
{
Res[i][j] = Res[i][j] + MissingYears * RiskAvg[i] * RiskAvg[j];
}
}
//Covariance Matrix
for (i = 0; i < RiskNo; i++)
{
//SD
RiskSD[i] = sqrt(RiskSD[i] / (NoSimYear - 1));
if (RiskSD[i] == 0.0)
{
RiskSD[i] = 1.0;
}
//Covar
for (j = i + 1; j < RiskNo; j++)
{
Res[i][j] = Res[i][j] / (NoSimYear - 1);
}
}
//Correlation Matrix
for (i = 0; i < RiskNo; i++)
{
Res[i][i] = 1.0;
for (j = i + 1; j < RiskNo; j++)
{
Res[i][j] = Res[i][j] / (RiskSD[i] * RiskSD[j]);
}
}
//Clean up
delete[] RiskTrack;
delete[] RiskTrackBool;
delete[] RiskAvg;
delete[] RiskSD;
//Return Array
return Res;
}
Def File
LIBRARY CorrelLib
EXPORTS
CalcMatrix
VB.NET
I've created a simple winform with a button which triggers the code below. I wish to link to the dll, pass the arrays and receive the result as a 2d array.
Imports System
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("CorrelLib.dll", EntryPoint:="CalcMatrix", CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function CorrelMatrix2(ByRef Risk_FE As Integer, ByRef Year_FE As Integer, ByRef Loss_FE As Double, _
ByRef RowNo As Long, ByRef RiskNo As Long, ByRef NoSimYear As Long) As Double(,)
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer, j As Integer
Dim Risk() As Long, Year() As Long, Loss() As Double
Dim NoRisks As Long, NoSimYear As Long, NoRows As Long
Dim counter As Long
Dim Result(,) As Double
NoRisks = 50
NoSimYear = 10000
NoRows = NoRisks * NoSimYear
ReDim Risk(0 To NoRows - 1), Year(0 To NoRows - 1), Loss(0 To NoRows - 1)
counter = 0
For i = 1 To NoSimYear
For j = 1 To NoRisks
Risk(counter) = j
Year(counter) = i
Loss(counter) = CDbl(Math.Floor((1000000 - 1 + 1) * Rnd())) + 1
counter = counter + 1
Next j
Next i
Dim dllDirectory As String = "C:\Users\Documents\Visual Studio 2013\Projects\CorrelLibTestForm"
Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + dllDirectory)
Result = CorrelMatrix2(Risk(1), Year(1), Loss(1), NoRows, NoRisks, NoSimYear)
End Sub
End Class
Current Error Message
An unhandled exception of type >'System.Runtime.InteropServices.MarshalDirectiveException' occurred in >CorrelLibTestForm.exe
Additional information: Cannot marshal 'return value': Invalid >managed/unmanaged type combination.
A double ** pointer to a pointer is not the same with a 2 dimension array in vb. Your best bet is to return just a pointer:
double *pdbl;
pdbl = &res[0][0];
return pdbl; //pdbl points to the first element
In vb you use an IntPtr to get the pointer:
Dim Result As IntPtr = Marshal.AllocHGlobal(4)
Dim dbl As Double
Result = CorrelMatrix2(Risk(1), Year(1), Loss(1), NoRows, NoRisks, NoSimYear)
//derefference the double pointer, i(integer) is actually the index in the array of doubles
dbl = CType(Marshal.PtrToStructure(IntPtr.Add(Result, i * 8), GetType(Double)), Double)
Your res array in c++ function needs to be public so the memory allocated to it is valid after the function returns.

How to find maximum area among given triangles on C++

The input should be n - the number of triangles (1 <= n <= 20) and afterwards n rows of three doubles each (corresponding to each of the triangles' sides). The output should be the "n" which has the maximum triangle area.
#include <iostream>
#include <math.h>
using namespace std;
const int MAX_SIZE = 20;
int main()
{
int n, s, p;
double max = 0;
cin >> n;
int x[MAX_SIZE];
for (int i = 0; i < n; i++)
{
double y[2];
for (int j = 0; j < 3; j++)
cin >> y[j];
p = (y[0] + y[1] + y[2]) / 2;
s = sqrt(p * (p - y[0]) * (p - y[1]) * (p - y[3]));
if (s >= max) max = s;
}
cout << max;
return 0;
}
That's what I've done so far. "p" stands for semiparameter by the way.. - I'm using Heron's formula. I haven't even got it to "cout" the n in which the area is max but rather the maximum area itself, yet it doesn't work but gives me a massive error instead. Any ideas?
You've got a few problems:
You need to change s and p from ints to doubles (otherwise you'll get unwanted truncation of your results).
You need to change double y[2]; to double y[3]; (since you need three side lengths, not two).
Change s = sqrt(p * (p - y[0]) * (p - y[1]) * (p - y[3])); to s = sqrt(p * (p - y[0]) * (p - y[1]) * (p - y[2])); (since y[3] is out of bounds of your array).
Note also that you can get rid of your array x, since you don't seem to actually use it anywhere.
You are allocation only 2 doubles. You need 3, try double y[3].