struct Test1 {
struct Test2 {
DWORD VA1 = 0;
DWORD VA2 = 0;
Test2(DWORD hp):VA1(hp) { }
} *Ppy[5];
Test1() {
for (int i = 0; i < 5; i++)
*(Ppy + i) = new Test2((DWORD)i+2);
}
~Test1() {
for (int i = 0; i < 5; i++)
delete *(Ppy + i);
}
};
void main() {
Test1*Als = new Test1;
for (int i = 0; i < 5; i++)
Als->Ppy[i]->VA2;
// doesn't work-> cout << Als->*(Ppy + i)->VA2 << endl;
delete Als;
}
Hello
How to convert this whole line(if possible) or at least Ppy[i] to
Pointer style/arithmetic : Als->Ppy[i]->VA2
Something like this but it doesn't work : Als->*(Ppy + i)->VA2
Is there a way to make this even more complex (not asm deep)?
Instead of:
Als->Ppy[i]->VA2;
You can write:
(*(Als->Ppy + i))->VA2;
The pointer to the array is Als->Ppy
The pointer to an element of the array is Als->Ppy + i
The value of an element of the array is *(Als->Ppy + i)
The value of an element of the array is itself a pointer, and you need to wrap the above expression in parens before using it to point to an element of the structure.
Related
This question already has answers here:
How to return an array from a function?
(5 answers)
Closed 2 years ago.
Why is it necessary to define an array as a global variable when returning an array in a function?
int v[10] = { 1,2,3,44,55,66,77,8,9,1 };
auto fun()->int(*)[10]
{
//int v[10] = { 1,2,3,44,55,66,77,8,9,1 };/
return &v;
}
int main()
{
auto t = fun();
for (int i = 0; i <= 10; i++)
cout << (*t)[i] << endl;
}
First, your code is C++ and not C, so I'll respond accordingly.
You can return a C++-style std::array, which is an object rather than a C-style array and thus can be returned by value:
#include <iostream>
#include <array>
int v[10] = { 1,2,3,44,55,66,77,8,9,1 };
auto fun()->std::array<int, 10>
{
std::array<int, 10> v;
v[0] = 5;
v[1] = 32;
//int v[10] = { 1,2,3,44,55,66,77,8,9,1 };/
return v;
}
int main()
{
auto v = fun();
for(size_t i = 0; i < 10; i++) {
std::cout << v[i] << std::endl;
}
}
You could have dynamically allocated the array instead, in which case you return a pointer and the caller is responsible for freeing it:
auto fun2()->int*
{
auto v = new int[10];
v[0] = 1;
// assign other elements
return v;
}
int main()
{
auto t2 = fun2();
for (int i = 0; i < 10; i++)
std::cout << t2[i] << std::endl;
delete[] t2;
}
You're simply not allowed to allocate the array on the stack and then return it, because the lifetime of stack variables is over as soon as your function returns. With that said, this example is valid because the array is allocated in main's stack frame and outlives all of its uses:
void fillIn(int* ar, size_t len) {
for (size_t i = 0; i < len; i++) {
ar[i] = 32; // or whatever logic you want
}
}
int main()
{
int x[10];
fillIn(x, 10);
for (int i = 0; i < 10; i++) {
std::cout << x[i] << std::endl;
}
}
int* filtrationBiggerValues(int* values, int nrValues, int givenValue) {
int j = 0;
int *new_array=NULL;
new_array = new int[nrValues];
for (int i = 0; i < nrValues; i++)
if (values[i] >= givenValue)
{
new_array[j] = values[i];
j++;
}
return new_array;
}
void main() {
int y[] = { 1,2,100,18,20,94 };
cout<< filtrationBiggerValues(y, 6, 8)<<"\n";
}
I should see the new array with the values bigger than a certain value, but instead I get its address.
That is not how it works. You are returning a pointer from your function not the value. If you want to see the values as output you should iterate on the array and print out each element separately. Also note returning size of your output array from the function for easy iteration.
int* filtrationBiggerValues(int* values, int nrValues, int givenValue, int& outputSize) {
int j = 0;
int *new_array=NULL;
new_array = new int[nrValues];
for (int i = 0; i < nrValues; i++)
if (values[i] >= givenValue)
{
new_array[j] = values[i];
j++;
}
outputSize = j;
return new_array;
}
void main()
{
int y[] = { 1,2,100,18,20,94 };
int outputSize = 0;
int* output = filtrationBiggerValues(y, 6, 8, outputSize);
for(int i=0; i<outputSize; ++i)
{
cout<< output[i] <<"\n";
}
}
Update (If you want to keep signature of the function as it is)
int* filtrationBiggerValues(int* values, int nrValues, int givenValue) {
int j = 0;
int *new_array=NULL;
new_array = new int[nrValues];
for (int i = 0; i < nrValues; i++)
if (values[i] >= givenValue)
{
new_array[j] = values[i];
j++;
}
new_array[j] = 0;
return new_array;
}
void main()
{
int y[] = { 1,2,100,18,20,94 };
int* output = filtrationBiggerValues(y, 6, 8);
for(int i=0; output[i]>0; ++i)
{
cout<< output[i] <<"\n";
}
}
the name of the array is actually a pointer.
if you try this:
int main()
{
int y[] = { 1,2,100,18,20,94 };
cout << y <<endl;
cout<< filtrationBiggerValues(y, 6, 8)<<"\n";
return 0;
}
the output is two address
0x7ffd7ac2bc10
0xfadc30
So much to say:
int* new_array = NULL; C++ uses nullptr. I.e. int* new_array = nullptr;
However, you should inlue the initialization you do next line:
int* new_array = new int[nrValues];
But you just created a new object on the heap, that you don't delete. That is called a memory leak.. Nowadays we use unique pointers to help us there.
std::unique_ptr<int[]> new_array = new int[nrValues];
However, in C++ we have STL containers handle all the C-style array stuff for you. As new_array is a different size then values, you probably want to use std::vector, which has a dynamic size. The STL containers have something called iterators, which can go over the element more efficiently. However, the STL containers don't have default output functions, so you'll have to write your own.
#include<vector>
#include<iostream>
std::vector<int> getBiggerThen(std::vector<int> const& input, int givenValue) {
std::vector<int> output;
for (auto it = input.cbegin(); it != input.cend(); it++) {
if (*it > givenValue) {
output.push_back(*it);
}
}
return output;
}
std::ostream& operator<< (std::ostream& out, std::vector<int> const& vec) {
for (auto const& el : vec) out << el << " ";
return out;
}
int main() {
auto y = std::vector<int>{ 1,2,100,18,20,94 };
std::cout << getBiggerThen(y, 8) << "\n";
}
oh... also important: in C++ main should always return an int.
Finally, what you are doing is required so often, that the STL library has an built-in algorithm for it. Which can reduce everything to
#include<vector>
#include<algorithm>
#include<iostream>
int main() {
auto y = std::vector<int>{ 1,2,100,18,20,94 };
std::vector<int> output{};
int givenValue = 8;
std::copy_if(std::cbegin(y), std::cend(y), std::back_inserter(output),
[givenValue](int val) { return val >= givenValue; });
for (auto const& el : output) std::cout << el << " ";
std::cout << "\n";
}
When is it better to have a function return a pointer to an array, like this:
int * foo(int n) {
int * output = new int[n];
for (int i = 0; i < n; i++) {
output[i] = i;
}
return output;
}
int main() {
int * arr = foo(10);
return 0;
}
vs having the function not return anything but just set values of an array given in the parameters, like this:
void foo(int n, int output[]) {
for (int i = 0; i < n; i++) {
output[i] = i;
}
}
int main() {
int arr[10];
foo(10, arr);
return 0;
}
For example, I have a function that generates prime numbers, and I would like to return them as an array. Should I use the first option and return a pointer to the array, or pass an array into the function and put the values in that?
When sould I return a pointer to an array
When you have a function that creates an array - but there are better ways to do it in C++ than to return a raw pointer to the memory (since those pointers are easy to forget about so you get memory leaks etc). You can for example use the dynamic array-like std::vector:
std::vector<int> foo(size_t n) {
std::vector<int> output(n);
for(size_t i = 0; i < n; ++i)
output[i] = i;
return output;
}
std::vector<int> arr = foo(10);
std::cout << arr.size() << "\n";
std::cout << arr[9] << "\n";
vs setting values in an existing array
When you already have an array that you want to use as input and you want to modify it.
void foo(std::vector<int>& inout) {
for(int& val : inout)
val += 10; // add 10 to every element
}
I'm pretty new to C++ and I have some problems with getting into all that pointer stuff. Basically I am passing a pointer to a Function, creating an Array at that pointer. Back in the main function I can't access this array.
Here's my code:
#include <iostream>
using namespace std;
void createArray(char** dict, int* arraysize)
{
*arraysize = 26*26*26*26;
delete dict;
dict = 0;
//Initialisiere character array of character
//char **wortliste = 0;
dict = new char*[*arraysize];
for(int i = 0; i < *arraysize; i++)
dict[i] = new char[5];
int ctr = 0;
//Erstelle Einträge (sortiert)
for (char i = 'A'; i <= 'Z'; i++)
{
for (char j = 'A'; j <= 'Z'; j++)
{
for (char k = 'A'; k <= 'Z'; k++)
{
for (char l = 'A'; l <= 'Z'; l++)
{
dict[ctr][0] = i;
dict[ctr][1] = j;
dict[ctr][2] = k;
dict[ctr][3] = l;
dict[ctr][4] = '\0';
ctr++;
}
}
}
}
}
int main(void)
{
char** dict = 0;
int arraysize;
createArray(dict, &arraysize);
cout << dict[0] << endl << dict[arraysize-1] << endl;
return 0;
}
I can't figure out my error thank you very much in advance.
In C++ parameters are pass by value (unless explicitly marked as being reference parameters), so when you pass dict, a pointer (to a pointer to char) to createArray, the dict inside your function is a different object, albeit with the same initial value, as the dict in main. If you want to see changes to dict in main you would have to pass it by reference, or pass the address of it into a function taking a char ***.
E.g.
void createArray(char**& dict, int* arraysize)
or
void createArray(char*** pdict, int* arraysize)
{ // use (*pdict) instead of dict ...
and
// ...
createArray(&dict, &arraysize);
A more "C++" way to achieve what you want would be to have:
void createArray( std::vector<std::string>& dict );
and to simply have createArray resize the vector to the required size. Using standard containers like vector and string also frees you of the obligation to explicity deallocate that memory that you allocate which is currently missing from your code.
There are a couple of mistakes.
To delete an array:
char **array = /* new with whatever */;
/* do your work */
for (i = 0; i < array_size; ++i)
delete[] array[i];
delete[] array;
To new an array:
char **array = new char *[array_size];
for (i = 0; i < array_size; ++i)
array[i] = new char[array_size_2];
When deleteing, to make sure you don't iterate over a not-newed array, check it against NULL:
for (i = 0; i < array_size; ++i)
{
if (array[i] != NULL) /* Or simply if (array[i]) */
delete[] array[i];
array[i] = NULL;
}
if (array != NULL)
delete[] array;
array = NULL;
alternatively, since delete makes a check for NULL anyway, you can simplify this to:
if (array != NULL)
for (i = 0; i < array_size; ++i)
delete[] array[i]; /* no need to set to NULL after if going to delete the array */
delete[] array;
array = NULL;
Note: delete deletes a single object while delete[] deletes an array.
I can't imagine what you would do with such data, but you can at least use modern techniques.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<string> create() {
vector<string> result;
for (char i = 'A'; i <= 'Z'; ++i) {
for (char j = 'A'; j <= 'Z'; ++j) {
for (char k = 'A'; k <= 'Z'; ++k) {
for (char l = 'A'; l <= 'Z'; ++l) {
result.push_back(string() + i + j + k + l);
}
}
}
}
return result;
}
int main() {
vector<string> data = create();
cout << data.front() << endl << data.back() << endl;
}
Code
#include "stdafx.h"
#include <iostream>
void someFunc(double* pDoubleArray, int length)
{
double* pNewDoubleArray = new double[length];
for(int i = 0; i < length; i++)
{
pNewDoubleArray[i] = i * 3 + 2;
}
pDoubleArray = pNewDoubleArray;
}
int main()
{
double dbls[] = { 1, 2, 3, 4, 5 };
int length = sizeof dbls / sizeof dbls[0];
std::cout << "Before..." << std::endl;
for(int i = 0; i < length; i++)
{
std::cout << dbls[i] << ", ";
}
std::cout << std::endl;
someFunc(dbls, length);
std::cout << "After..." << std::endl;
for(int i = 0; i < length; i++)
{
std::cout << dbls[i] << ", ";
}
std::cout << std::endl;
while(true){ }
return 0;
}
Output
Before...
1, 2, 3, 4, 5,
After...
1, 2, 3, 4, 5,
Here's what I am trying to do:
1. Create an array and fill it with some values
2. Pass that array as a pointer to a function that will create a new array and reassign the one that was passed in to the newly created array
3. Print out the changes
I am not seeing any changes though, and I do not know why.
The interface of your function someFunc is wrong. It should require the reference of a pointer's address (or the pointer to a pointer) so that you can return the address of your new array. Otherwise, you are simply modifying a local value.
void someFunc(double*& pDoubleArray, int length)
{
double* pNewDoubleArray = new double[length];
for(int i = 0; i < length; i++)
{
pNewDoubleArray[i] = i * 3 + 2;
}
pDoubleArray = pNewDoubleArray;
}
Your calling main function should then pass a value which can be modified:
int main()
{
double dbls[] = { 1, 2, 3, 4, 5 };
double* pArray = dbls;
// ...
someFunc(pArray, length);
// ...
for(int i = 0; i < length; i++)
{
std::cout << pArray[i] << ", ";
}
// ...
}
Ignoring the memory leak issue that results:
void someFunc(double* & pDoubleArray, int length)
// pass by reference ^^^ the pointer
The line pDoubleArray = pNewDoubleArray; assigns the local copy of the pointer
Either pass the pointer by reference, pass a pointer to it, or return the new value
My preference would be to return the new value, bit that's a style issue.
It is unclear why you are passing the old array to a function which does not use it.
If you are changing individual values, then there is no point in creating a new array instance. If not, then simply create a new array and return it.
So, either change the original array:
void someFunc(double* pDoubleArray, int length)
{
for(int i = 0; i < length; i++)
{
pDoubleArray[i] = i * 3 + 2;
}
}
Or return the new array from the function:
// this indicates that the returned value is
// actually a new instance
double* getNewArray(double* pDoubleArray, int length)
{
double* pNewDoubleArray = new double[length];
for(int i = 0; i < length; i++)
{
pNewDoubleArray[i] = i * 3 + 2;
}
return pNewDoubleArray;
}
An alternative is to pass the input array by reference, but that complicates releasing unused instances.
[Edit]
To clarify this last case:
void someFunc(double** pDoubleArray, int length)
{
double* pNewDoubleArray = new double[length];
for(int i = 0; i < length; i++)
{
pNewDoubleArray[i] = i * 3 + 2;
}
*pDoubleArray = pNewDoubleArray;
}
void main()
{
double dbls[] = { 1, 2, 3, 4, 5 };
double* pArray = dbls;
// this will change what pArray
// points to
someFunc(&pArray, 5);
return 0;
}
As I've commented before, the latter approach will lead to memory leaks if pArray points to a heap allocated array before calling someFunc.