So, I recently tried doing this:
void Foo(int **bar, int size) {
bar = new int *[size];
for (int i = 0; i < size; i++)
bar[i] = new int[4];
// Do other stuff
return;
}
int main(int argc, char *argv[]) {
int ** data;
int size = atoi(argv[1]);
Foo(data, size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < 4; j++)
cout << "i = " << i << ", j = " << j << ", data = " << data[i][j] << endl;
// Do other stuff
}
for (int i = 0; i < size; i++)
delete[] data[i];
delete[] data;
return 0;
}
and invariably I would get a segfault right at that cout statement. After changing the code so that the array was dynamically allocated in main the problem went away. So, the difference between a segfault is whether or not an array is dynamically allocated and destroyed in the same function. This seems wrong to me as this shouldn't be a problem with traditional C++. I am using a MacBook with Xcode for the g++ command. Can anyone else confirm that Xcode's implementation does this?
It's nothing specific to Xcode or g++ - just a bug in your code - you need to pass bar by reference in order to use it as an output parameter.
Change:
void Foo(int **bar, int size)
to:
void Foo(int ** &bar, int size)
Note that in general it's preferable to use e.g. std::vector rather than naked C-style pointers for arrays etc.
You pass data to Foo by value, so data in main () remains uninitialized when you allocate memory inside Foo.
Related
Here is what I have so far: http://cpp.sh/54vn3
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <cstdlib>
using namespace std;
int *reSIZE(int *&original, int &SIZE, const int &maxSIZE); //function prototype resize
void sortFUNC(int *&original, int &SIZE, const int &maxSIZE); //function prototype sortFUNC
int main()
{
int SIZE = 4; //size of current array
int maxSIZE = 10; //size of final array
int *original = new int[SIZE] {5, 7, 3, 1}; //old(current) array
cout << "Elements in array: "; //test output
reSIZE(original, SIZE, maxSIZE); //call function resize
cout << endl << endl; //blank line
cout << "Elements in array in increasing order: "; //test output
sortFUNC(original, SIZE, maxSIZE); //call function sortFUNC
cout << endl << endl;
return 0;
}
int *reSIZE(int *&original, int &SIZE, const int &maxSIZE)//function definition
{
int *temporiginal = new int[SIZE + 3]; //(final)new array
for (int i = 0; i < SIZE; i++) //copy old array to new array
{
temporiginal[i] = original[i];
cout << original[i] << setw(3);
}
delete[] original; //delete old array
original = temporiginal; //point old array to new array
return temporiginal;
}
void sortFUNC(int *&original, int &SIZE, const int &maxSIZE)
{
for (int i = 0; i < SIZE; i++)
{
int smallest = original[i];
int smallestINDEX = i;
for (int m = i; m < SIZE; m++)
{
if (original[m] < smallest)
{
smallest = original[m];
smallestINDEX = m;
}
}
swap(original[i], original[smallestINDEX]);
}
int *temporiginal = new int[SIZE + 3];
for (int i = 0; i < SIZE; i++)
{
temporiginal[i] = original[i];
cout << original[i] << setw(3);
}
delete[] original;
original = temporiginal;
}
I want to add a few elements at the end of the array in main, but when I do, the program crashes when I run it. The resize function that I created is supposed to expand the function in main to hold 10 elements. The one in main originally holds 4. The new array is supposed to change that to 10. How do I add three more integers to the array in main without it crashing? Is my resize function wrong? Or is it a problem in my main? The program that is shown right now works as is. But when I add another integer in the array in main, it crashes. Like, if I add a 2 after the 1.
Thanks.
Edit: I was able to add elements at the end of the array in main by adding them in the resize function.
cpp.sh/35mww
Like mentioned earlier, maxSIZE isn't being used. There are more useless stuff as well. I have to clean this up, but I figured out what I was trying to figure out. I don't know how to use structures yet. I know that there are a lot of different ways to write a program. I'm just a beginner.
Thanks, everyone.
You need to modify the value of size everytime you call the function rezise other wise even if u call the function resize 3 times u always will have SIZE+3 on your array size.After call resize try
original[4] = 0;
original[5] = 0;
original[6] = 0;
and after that try to do this.
original[7] = 0;
you should be able to see your mistake
I am trying to understand passing by reference and passing by value. In this program I have a two dimensional array which is declared in main and whose size is allocated in a function. In the allocate2DArrayRef() function, I obtain the two sizes and dynamically allocate and initialize the array Array2D.
Now I am trying to understand how to do the same by pointers. I have written another function allocate2DArrayPtr() in where I pass a pointer to the two dimensional array, get the value of the sizes - sizeX and sizeY and then allocate the memory to the variable secArray2D.
When I run the program it hangs when I try to print out secArray2D. I am assuming this implies that the function allocate2DArrayPtr() has not been successful in dynamically allocating memory to the array secArray2D.
My final goal is to write a program which has a function that dynamically allocated memory and initializes multiple arrays of various dimensions which are read from an input file. I know I can expand on passing by reference function allocate2DArrayRef() to achieve my goal. But I am curious to learn why my function allocate2DArrayPtr() is not working as I want to be clear on how to pass by pointers also. I do know how to change allocate2DArrayPtr() to return a pointer but I would like to pass the array as a parameter.
I am running the program on windows 7 using Codeblocks 13.12 IDE.
#include <iostream>
using namespace std;
void allocate2DArrayRef(int **&, int &, int &);
void allocate2DArrayPtr(int ***, int *, int *);
int main()
{
int sizeX, sizeY;
int **Array2D;
allocate2DArrayRef(Array2D, sizeX, sizeY);
for(int i=0; i< sizeX; i++)
{
for(int j=0; j< sizeY; j++)
{
cout << "Array2D[" << i << "][" << j << "]:" << Array2D[i][j] << endl;
}
}
cout << endl << endl;
int **secArray2D;
allocate2DArrayPtr(&secArray2D, &sizeX, &sizeY);
for(int i=0; i<sizeX; i++)
{
for(int j=0; j<sizeY; j++)
{
cout << "secArray2D[" << i << "][" << j << "]:" << secArray2D[i][j] << endl;
}
}
return 0;
}
void allocate2DArrayRef(int **&locArray, int& indexFirst, int& indexSecond)
{
indexFirst = 4;
indexSecond = 5;
locArray = new int*[indexFirst];
for(int i=0; i<indexFirst ; i++)
{
locArray[i] = new int[indexSecond];
for(int j=0; j<indexSecond; j++)
{
locArray[i][j] = i*j;
}
}
}
void allocate2DArrayPtr(int ***locArray, int *indexFirst, int *indexSecond)
{
*indexFirst = 2;
*indexSecond = 3;
int **temp = *locArray;
temp = new int*[*indexFirst];
for(int i=0; i<(*indexFirst) ; i++)
{
temp[i] = new int[*indexSecond];
for(int j=0; j<(*indexSecond); j++)
{
temp[i][j] = i+j;
}
}
}
The reason allocate2DArrayPtr does not work is you never set locArray to point to the array you create in the function. This means when you return from the function secArray2D still is uninitialized.
Adding
*locArray = temp;
To the end of allocate2DArrayPtr will fix the problem.
Or you can reference your to temp like this:
int **&temp = *locArray;
This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 7 years ago.
I'm relatively new at c++ and other object oriented languages as a whole (have done one semester of C classes and now I'm having c++ classes). I'm having problems concerning the making of a dynamically allocated two-dimensional array through a class with a classmate.
The exercise itself would be:
Prepare a class named "matrix" capable of storing two-dimensional
arrays dynamically allocated (for float variables). Remember that
information such as height and width have to be properly stored
somewhere, element pointers too.
The class needs to contain constructors that allow the creation of
objects using one of the following strategies: The creation of an
array consisting of MxN elements, example:
Array A (4, 5);
The creation of an empty array:
Array B;
The creation of an array that is a copy of another previous one:
Array C (A);
After some time trying to figure out why it wasn't working properly, our code is currently this:
obs: "Matriz" is how we call a two-dimensional array in our language.
Matriz.h
#pragma once
class Matriz{
public:
int l, c;
float** matriz;
void setL(int _l);
void setC(int _c);
int getL();
int getC();
Matriz();
Matriz(int _l, int _c);
Matriz(Matriz& m);
float **getMatriz();
float getElement(int pL, int pC);
void setElement(int pL, int pC, float value);
};
Matriz.cpp
#include "Matriz.h"
Matriz::Matriz(){
l = c = 0;
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
}
Matriz::Matriz(Matriz& m){
l = m.getL();
c = m.getC();
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
for (int i = 0; i<l; i++) {
for (int j = 0; j<l; j++) {
matriz[i][j] = m.matriz[i][j];
}
}
}
Matriz::Matriz(int _l, int _c){
l = _l;
c = _c;
matriz = new float*[l];
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
}
float **Matriz::getMatriz(){
return matriz;
}
int Matriz::getC(){
return c;
}
int Matriz::getL(){
return l;
}
void Matriz::setC(int _c){
c = _c;
}
void Matriz::setL(int _l){
l = _l;
}
float Matriz::getElement(int pL, int pC){
return matriz[pL][pC];
}
void Matriz::setElement(int pL, int pC, float value){
matriz[pL][pC] = value;
}
main.cpp
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int l = 2, c = 2;
float **m;
m = new float*[l];
for (int i=0; i<2; i++) {
m[i] = new float[c];
}
Matriz a(2, 2);
a.setC(2);
a.setL(2);
cout << " c = " << a.getC() << " l= " << a.getL() << "\n";
for (int i = 0; i<l; i++) {
for (int j = 0; j<c; j++) {
a.setElement(i, j, 0);
cout << " Elemento " << 1 << " " << 1 << " = " << a.getElement(l, c) << "\n";
}
}
a.setElement(0, 0, 1); // <- this is just for testing
system("pause");
}
iostream and the class header are both included at stdafx.h
Compiling it at MSVS 2013 breaks at
void Matriz::setElement(int pL, int pC, float value){
matriz[pL][pC] = value;
}
And we're not really sure why, the debugger is giving me
"Unhandled exception at 0x01092E27 in ConsoleApplication15.exe: 0xC0000005: Access violation writing location 0xCDCDCDD1."
We suspect however that something with the array is wrong, and when the program tries to write something into an element of it, it simply doesn't exist/can't be reached, making it impossible to change the value of that specific element.
We're thankful for any help or advice, fell free to suggest improvements or coding advices, learning new things is always good =).
I think your error is actually here: a.getElement(l, c). l and c are the bounds for the array, e.g. 2, when your largest index should only ever be 1.
The other serious flaw (pointed out by twsaef) is your constructor:
for (int i = 0; i<l; i++) {
matriz[l] = new float[c];
}
Should be
for (int i = 0; i<l; i++) {
matriz[i] = new float[c];
}
While I'm at it, this is redundant:
Matriz a(2, 2);
a.setC(2);
a.setL(2);
Because the constructor for Matriz will set l and c for you.
Also, what are you planning on doing with this:
float **m;
m = new float*[l];
for (int i=0; i<2; i++) {
m[i] = new float[c];
}
Currently it's not used for anything.
Then, as PaulMcKenzie pointed out, what will happen to your dynamically allocated memory when a Matriz instance goes out of scope?
As Matt McNabb pointed out, what if you need to resize a Matriz instance when setC() or setL() are called? At the moment, they only set the member variable and do nothing with the memory.
I am trying to switch the elements of a class array using pointers. It is not outputting what I want. I tried using pointers in the function, but it's not allowed. It's also not allowed to call the function onto the class object without using a pointer, since I declared the class object using a double pointer. I am not using this method simply to solve a small problem, but just to practice using this method for more difficult problems.
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
class thing{
public:
int index;
int value;
thing();
private: int number;
};
thing::thing()
{
number = 0;
}
void arrange(thing array[]){
for(int i=0; i<19; ++i){
if(array[i].value<array[i+1].value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
int main(){
thing** things = new thing*[20];
for (int i=0; i < 20; ++i)
{
things[i] = new thing(); // default constructor
things[i]->index = i;
things[i]->value=rand() % 100;
}
cout << "The random array is: " << endl;
for(int i=0;i<20;++i){
cout << things[i]->value << endl;
}
arrange(*things);
cout << "The arranged array is: " << endl;
for (int i=0; i < 20; ++i)
{
cout << things[i]->value << endl;
}
return 0;
}
When you call arrange(*things), you're just passing the first element of things to the function, not the array. It should be array(things). Then the arrange function should be written to use pointers:
void arrange(thing* array[]){
for(int i=0; i<19; ++i){
if(array[i]->value<array[i+1]->value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
Here you create an array of pointers to thing:
thing** things = new thing*[20];
Here you dereference it and get a pointer to thing which is stored at thing[0]:
arrange(*things);
But this function declaration
void arrange(thing array[])
treats this pointer as an array of thing, so that *things points to it first element, which is absolutely not what it really is.
You should change your arrange() function to use correct type:
void arrange(thing* array[]){
for(int i=0; i<19; ++i){
if(array[i]->value<array[i+1]->value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
And call it as:
arrange(things);
Regarding using vectors, you don't need to use any pointers at all.
std::vector<thing> things(20);
for (int i=0; i < things.size(); ++i)
{
things[i].index = i;
things[i].value=rand() % 100;
}
arrange(things);
void arrange(std::vector<thing>& array){
for(int i=0; i + 1 < things.size(); ++i){
if(array[i].value<array[i+1].value){
swap(array[i], array[i+1]);
arrange(array);
}
}
}
I'm trying to create a function that would dynamically allocate an array, sets the values of the elements, and returns the size of the array. The array variable is a pointer that is declared outside the function and passed as a parameter. Here is the code:
#include <cstdlib>
#include <iostream>
using namespace std;
int doArray(int *arr) {
int sz = 10;
arr = (int*) malloc(sizeof(int) * sz);
for (int i=0; i<sz; i++) {
arr[i] = i * 5;
}
return sz;
}
int main(int argc, char *argv[]) {
int *arr = NULL;
int size = doArray(arr);
for (int i=0; i<size; i++) {
cout << arr[i] << endl;
}
return 0;
}
For some reason, the program terminates on the first iteration of the for loop in main()! Am I doing something wrong?
If you want to allocate memory that way you have to use:
int doArray(int*& arr)
else the pointer will only be changed inside the function scope.
You're passing in the array pointer by value; this means that when your doArray function returns, the value in arr in main is still NULL - the assignment inside doArray doesn't change it.
If you want to change the value of arr (which is an int *), you need to pass in either a pointer or a reference to it; hence, your function signature will contain either (int *&arr) or (int **arr). If you pass it in as a ** you'll also have to change the syntax inside the function from using arr to *arr (pointer-dereferencing), and you'll call it like so: doArray(&arr).
Also, in C++ you should really be using new int[sz] instead of malloc.
You need to add an extra level of indirection to doArray. As written it allocates the array properly but it doesn't communicate the pointer value back to the caller correctly. The pointer from malloc is lost once you return.
If you wrote a function to take a float and change the value, passing the changed value back to the caller, it would need to take a pointer: foo(float *f). Similarly, here you want to pass back an int* value to the caller so your function must be declared as doArray(int **arr) with a second asterisk.
int doArray(int **arr) {
int sz = 10;
*arr = (int*) malloc(sizeof(int) * sz);
for (int i=0; i<sz; i++) {
(*arr)[i] = i * 5;
}
return sz;
}
int main(int argc, char *argv[]) {
int *arr = NULL;
int size = doArray(&arr);
for (int i=0; i<size; i++) {
cout << arr[i] << endl;
}
return 0;
}
Notice how it now dereferences *arr inside of doArray, and how the call is now written as doArray(&arr).
The arr variable in your function is a local copy of the arr pointer in the main function, and the original is not updated. You need to pass a pointer-to-pointer or pointer reference (the former will also work in plain c, the later only in c++).
int doArray(int **arr)
or
int doArray(int*& arr)
Change signature to (specific for c++):
int doArray(int *&arr)
so pointer would be changed at exit from doArray.
You need a pointer to a pointer in your doArray() parameter. If you've never done any programming with pointers before, this can be confusing. I find that it can be easier to see the right types if you annotate your code abundantly with typedefs.
You have the right idea that (int*) can be used to represent an array. But if you want to change the value of your variable arr in main(), you need a pointer to that, and so you will end up with (untested code) something like the following
typedef int *IntArray;
int doArray(IntArray *arr) {
int sz = 10;
*arr = (IntArray) malloc(sizeof(int) * sz);
IntArray theArray = *arr;
for (int i=0; i<sz; i++) {
theArray[i] = i * 5;
}
return sz;
}
when calling doArray, you will need to pass the address of your variable (so doArray knows where to write to):
int main(int argc, char *argv[]) {
int *arr = NULL;
int size = doArray(&arr);
for (int i=0; i<size; i++) {
cout << arr[i] << endl;
}
return 0;
}
This should work.
As others have pointed out, you're passing your array (the int *) by value, so when you say arr=... you're not actually changing the array you passed in.
You're also got a memory leak, as you've written it. It's not a big deal when you only call doArray once in the body of your program, but if it gets called repeatedly and the array is never freed (or deleted, if you made it with new) then it can cause problems. Typically the best way to deal with this is by using the STL. You'd then write
#include <vector>
#include <iostream>
int doArray(std::vector<int> &arr) {
int sz = 10;
arr.resize(sz);
for (int i=0; i<sz; i++) {
arr[i] = i * 5;
}
return sz;
}
int main(int argc, char *argv[]) {
std::vector<int> arr;
int size = doArray(arr);
for (int i=0; i<size; i++) {
std::cout << arr[i] << std::endl;
}
return 0;
}
However, with the STL there are more idomatic ways than returning the size, since you can just ask for arr.size(), and if you get really fancy, can use functions like for_each or the ostream_iterator to print all your elements.