Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I'm struggling with removing the array from the memory.. it was allocated dynamically. I'd love some help, thanks!
void RemoveAllocationOfIntegerArray(int** arr, int size) {
for (int i = size - 1; i >= 0; i--) {
delete arr[i];
arr[i] = NULL;
}
delete[] arr;
arr = NULL;
}
First, you don't need these lines:
arr[i] = NULL;
// or
arr = NULL;
Next, you should delete arrays using delete[] operator. So, replace
delete arr[i];
with:
delete[] arr[i];
Another point is, you can free memory using delete or delete[] only if it is allocated with new or new[].
Lastly, You don't need to go backward when freeing. It is not necessary (except for some odd cases).
Example of using std::vector, or std::vectorstd::vector<int>
#include <format>
#include <vector>
#include <iostream>
void function_on_2d_data(std::vector<std::vector<int>>& values) // pass non const so you can modify values.
{
values[1][1] = 7;
}
void show_2d_data(const std::vector<std::vector<int>>& values) // pass const, show should not modify content
{
for (const auto& row : values)
{
for (const auto& value : row)
{
std::cout << value << " ";
}
std::cout << "\n";
}
}
// a function returning dynamically allocated 2d arrays (much more safe then int** with no size info);
std::vector<std::vector<int>> create_2d_data()
{
std::vector<std::vector<int>> values(4, std::vector<int>(3, 1)); // This does all the "new"-ing for you, and set values in each row to 1
return values;
}
int main()
{
// create a 2d datastructure containing 4 row and 3 columns;
std::vector<std::vector<int>> values = create_2d_data();
std::cout << std::format("values has {0} rows\n", values.size()); // see size information is returned too
function_on_2d_data(values);
show_2d_data(values);
return 0;
// values goes out of scope and it will do all the "delete"-ing for you
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I want to implement a dynamic array as a class.
I haven written a method which adds an element at the end of the array:
void DynamicArray::addElementAtEnd() {
cout << "\nPodaj liczbe calkowita: ";
int* number = new int;
cin >> *number;
if (DynamicArray::array == NULL) {
DynamicArray::array = new int[1];
DynamicArray::array[0] = *number;
delete number;
(*DynamicArray::size)++;
return;
}
int* buff = new int[*DynamicArray::size + 1];
memcpy(buff, DynamicArray::array, (*DynamicArray::size) * sizeof(int));
delete[] DynamicArray::array;
buff[(*DynamicArray::size)] = *number;
DynamicArray::array = buff;
(*DynamicArray::size)++;
delete number;
return;
};
Here's the .h file of the DynamicArray class:
#include <iostream>
using namespace std;
class DynamicArray {
public:
int* array;
int* size;
public:
DynamicArray() {
DynamicArray::size = new int;
*DynamicArray::size = 0;
};
void handleMenu();
void readFromFile();
void addElementAtEnd();
void addElementAtBeginning();
void addAtIndex(int index);
void deleteElementAtEnd();
void deleteElementAtBeginning();
void deleteElementByIndex(int index);
void showAllElements();
void showElementAtIndex(int index);
void findElementByValue(int value);
};
The problem is that this method adds only the first element, but if I try to add more then nothing happens. I debugged it, and the problem starts on this line:
int* buff = new int[*DynamicArray::size + 1];
I don't know why, but it seems like this line is not creating a bigger array.
I searched for some solutions, and it seems that the problem is connected with using *DynamicArray::size + 1 instead of eg a variable, or I don't do something right with it.
The actual problem is that you are not initializing array to NULL.
So when you check if array is NULL on the first iteration, it is often not.
The minimal solution:
DynamicArray::DynamicArray() {
this->size = 0; // You should use 'size' like an int, not a pointer
this->array = NULL;
}
// Or using the Member Initializer List (by #user4581301)
DynamicArray::DynamicArray(): size(0), array(nullptr) {}
Note: Differences between NULL and nullptr
Other simple solution could be to check if size is equal to 0 instead of checking if array is NULL.
The above change will solve your problem but your code can still be improved.
Take into account the comments of other users.
And make sure to free each dynamically allocated memory.
Let's address a variety of things.
class DynamicArray {
public:
int* array;
int* size;
public:
DynamicArray() {
DynamicArray::size = new int;
*DynamicArray::size = 0;
}
};
A few things here. First, as others have suggested, there's zero reason to make size a pointer.
Next, it's a strong guideline / good idea to always initialize your fields when declared.
So this section of code can look like this:
class DynamicArray {
public:
int* array = nullptr;
int size = 0;
public:
DynamicArray() {
}
};
After that, please use nullptr instead of NULL. NULL is from C, but the correct value in C++ is nullptr.
Now, let's look at this bit of code.
void DynamicArray::addElementAtEnd() {
cout << "\nPodaj liczbe calkowita: ";
int* number = new int;
cin >> *number;
if (DynamicArray::array == NULL) {
DynamicArray::array = new int[1];
DynamicArray::array[0] = *number;
delete number;
(*DynamicArray::size)++;
return;
}
int* buff = new int[*DynamicArray::size + 1];
memcpy(buff, DynamicArray::array, (*DynamicArray::size) * sizeof(int));
delete[] DynamicArray::array;
buff[(*DynamicArray::size)] = *number;
DynamicArray::array = buff;
(*DynamicArray::size)++;
delete number;
return;
};
Aside from the extra colon on the end of the function (entirely not necessary), this is far more complicated than it needs to be. First, get rid of the int pointer. That's just ridiculous.
void DynamicArray::addElementAtEnd() {
cout << "\nPodaj liczbe calkowita: ";
int number = 0;
cin >> number;
int * newArray = new int[size + 1];
newArray[size] = number;
if (array != nullptr) {
for (int index = 0; index < size; ++index) {
newArray[index] = array[index];
}
delete [] array;
}
array = newArray;
++size;
}
A last comment -- it would make far more sense to pass in the new value as an argument to the method, and the calling test code should get the value you're adding. But you're just learning, so this works.
Note also that you shouldn't specify the class the way you have: DynamicArray::array. No one does that. Do it the way I did above.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I am trying to make a function that has access to a specific element found in a vector. The goal is that the function would dynamically work with any element it is passed. I am not sure how else to implement this, but I am trying to use pointers and offsets, but I cant figure out how to properly calculate the offset since (afaik) pointer subtraction requires the same object type. Any help would be appreciated!!
This picture shows what I am trying to do on the right side (to get the target element in each item).
https://imgur.com/a/MvwRFaJ
#include <iostream>
#include <vector>
struct item
{
int numItems = 0;
float price = 0;
double foo = 0;
item(int num, float pr, double f)
{
numItems = num;
price = pr;
foo = f;
}
};
// GOAL: I can pass any target element of the vector as an argument,
// and have some sort of loop to print that element found in the entire vector
/// <summary>
/// This function prints any given target element through the entirety of a vector
/// </summary>
/// <param name="vecItemPtr"> Starts as the pointer to the first item found in the vector,
/// vecItemPtr is iterated after each targetElement is printed </param>
/// <param name="targetElemPtr"> Indicates the position of the element we are trying to
/// find in each item</param>
/// <param name="endIndex"> Indicates the number of items in the array that we will have to
/// iterate through</param>
template <class T>
void printValues(item* vecItemPtr, T* targetElemPtr, int numItems)
{
// I think It would be possible to do this by finding the
// 'offset' (in bytes) of the targetElement found in each item
// BUT these items are of different type (*int/*float/*double vs item*)
ptrdiff_t targetElementOffset = targetElemPtr - vecItemPtr;
// ^ Error C2440 '-': cannot convert from 'item *' to 'T*' IterateVectorPtr
for (int i = 0; i < numItems; i++)
{
// Print the value found at the address of the vecItemPtr PLUS the offset
printf("%f", *(vecItemPtr + targetElementOffset));
}
vecItemPtr++;
}
int main()
{
std::vector<item> test;
item item1(10, 3.0f, 8);
item item2(20, 1.0f, 4);
test.reserve(2);
test.push_back(item1);
test.push_back(item2);
// Say I want to print all numItems in the vector
printValues(&test[0], &test[0].numItems, test.size());
// Say I want to print all prices in the vector
printValues(&test[0], &test[0].price, test.size());
// Say I want to print all foo's in the vector
printValues(&test[0], &test[0].foo, test.size());
}
The reason your code doesn't work is because you are trying to perform pointer arithmetic using incompatible pointer types. Since you need to deal with byte offsets, you need to operate with byte pointers, eg:
template <class T>
void printValues(item* vecItemPtr, T* targetElemPtr, int numItems)
{
ptrdiff_t targetElementOffset = reinterpret_cast<char*>(targetElemPtr) - reinterpret_cast<char*>(vecItemPtr);
for (int i = 0; i < numItems; i++)
{
std::cout << *reinterpret_cast<T*>(reinterpret_cast<char*>(vecItemPtr + i) + targetElementOffset) << std::endl;
}
}
...
printValues(&test[0], &test[0].numItems, test.size());
printValues(&test[0], &test[0].price, test.size());
printValues(&test[0], &test[0].foo, test.size());
Demo
However, a safer and cleaner solution is to use a pointer-to-member instead, then you don't need to deal with byte offsets manually at all, eg:
template <class T>
void printValues(item* vecItemPtr, T item::* targetElemPtr, int numItems)
{
for (int i = 0; i < numItems; i++)
{
std::cout << (vecItemPtr[i].*targetElemPtr) << std::endl;
}
}
...
printValues(test.data(), &item::numItems, test.size());
printValues(test.data(), &item::price, test.size());
printValues(test.data(), &item::foo, test.size());
Demo
For more flexibility you can let the function take a functor. Don't use pointers, also don't pass the size seperate from the container. One benefit of using std::vector is that you need not do that. If you pass iterators, the same function will also work for other containers with ForwardIterators.
For example you might want to to let the function print the product of numItems and price:
#include <iostream>
#include <vector>
struct item {
int numItems = 0;
float price = 0;
double foo = 0;
item(int num, float pr, double f) : numItems(num), price(pr), foo(f)
{
// prefer the member initialization list over assignment in the constructors body
}
};
template <class IT,class F>
void printValues(IT begin, IT end, F f) {
for (; begin != end; ++begin) {
std::cout << f(*begin) << "\n";
}
}
int main() {
std::vector<item> test;
item item1(10, 3.0f, 8);
item item2(20, 1.0f, 4);
test.reserve(2);
test.push_back(item1);
test.push_back(item2);
printValues(test.begin(),test.end(),[](auto i){ return i.numItems;});
printValues(test.begin(),test.end(),[](auto i){ return i.numItems * i.price;});
}
Output:
10
20
30
20
I am a beginner programmer in school still, and I was assigned this problem:
"Make your own dynamic array template. It should allow creating contiguous arrays (filled with things of the same type) which you can extend without worrying about running out of space.
Do one version using malloc and free.
Do one version using new and delete."
So far this is what I have:
#include <iostream>
#include <sstream>
#include "Array.h"
using namespace std;
int main(){
Array<int> *testArray = new Array<int>(5);
testArray->initArray();
testArray->printArray();
testArray->addData(7);
testArray->printArray();
return 0;
}
And here is the "Array.h" file:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template<typename T>
class Array{
public:
Array(int size){
size = size;
data = new T[size];
};
Array<T> *addData(T dataToAdd){
Array <T> *tmp = new Array <T> (this->size);
tmp->data = this->data;
Array <T> *newData = new Array<T> (this->size + 1);
for (int i = 0; i < this->size + 1; ++i){
if (i < this->size){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
return newData;
};
void initArray(){
for (int i = 0; i < this->size; ++i){
//this->data[i] = i;
this->setData(i, i);
}
};
void printArray(){
ostringstream oss;
string answer = "";
for (int i = 0; i < this->size; ++i){
oss << this->data[i] + " ";
//cout << this->data[i] << " ";
}
answer = oss.str();
cout << answer << "asdf" << endl;
};
T* getData(){
return this->data;
}
int getSize(){
return this->size;
}
void setData(T data, int index){
this->getData()[index] = data;
}
private:
int size;
T* data;
};
So far what SHOULD happen in my main file is there should be an array of 5 ints, that are initialized to 0,1,2,3,4 from the initArray function.
Then it should print out the array, showing "0 1 2 3 4," add another "7" to it, then print the new array out showing "0 1 2 3 4 7."
For some reason, and I think it has something to do with losing data somehow when going between the two files, the field "data" of my Array class is not being properly changed.
I even hardcoded a test for this in main where I wrote a for loop using the setData function that initializes the Array to "0 1 2 3 4," and then manually printed out these values with another for loop, but the output was only "0 0 0 0 0."
Right now, as the code is, the output is:
asdf
asdf
As it was outputting whitespace before so I added the "asdf"'s to see if my printArray worked at all.
To sum up, why is the data in my private field "data" not being properly stored? I am very new to programming in c++ and any advice would be greatly appreciated. Thank you for your time, and if there is anything you do not understand please ask for clarification and I will do my best.
EDIT: problem solved! Thank you everyone who helped, the issue was with my constructor and how I was calling my functions in main.
One issue is your constructor:
Array(int size){
size = size;
data = new T[size];
};
The way you have it, you're just assigning your size argument to itself, which has no effect. One way to fix it would be to use a different name for the argument:
Array(int size_arg){
size = size_arg;
data = new T[size_arg];
};
However, the preferred way is to use the constructor initializer syntax:
Array(int size) : size(size), data(new T[size]) {};
With the constructor initializer syntax, the compiler knows that you are trying to initialize specific members and doesn't get confused between the argument name and the member name.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
EDIT (Remake): Here's what I'm trying to do:
char* someArray = new char[someIntVariable];
And then loop over the array and use a custom function to get the contents of the other array (that's where the problem lies):
char* temp = someFunc(someArray, someIntVariable); //someFunc is a char* returning function
for(int i = 0; i < someIntVariable; i++){
someArray[i] = temp[i] //temp[i] is where the problem lies. It returns something like: /213
}
Text version: I'm trying to get a pointer to a char array to return all of the arrays contents (only using one single pointer) and loop over a previously created array and fill it's spaces or somehow assign it one single assignment.
Hope this is comprehensible.
"someFunc":
char* convertCharArr(char* _inputArr, int arrSize){
char *inputArr = new char[arrSize];
std::memmove(inputArr, _inputArr, sizeof(*inputArr));
static char *resizedUsrInptAns = new char[arrSize];
for(int i = 0; i < sizeof(inputArr)/sizeof(inputArr[0]); i++){
if(i == arrSize + 1){
break;
}
resizedUsrInptAns[i] = inputArr[i];
}
return resizedUsrInptAns;
}
ptr2 and ptr1 are equivalent, so I am going to ignore ptr2 for my answer.
If you want to clone a char array of unknown size, you have to use dynamic memory allocation:
char * p = malloc(strlen(ptr1) + 1);
strcpy(p, ptr1);
// ...
free(p);
You can't assign a pointer to an array, thats impossible in c. You can only do the opposite, assigning an array to a pointer.
You will have to create a new array(with dynamic allocation) and copy the data into that array.
Example
char* pChar = GetArrayPointer();
char* pNewArrayPointer = (char*)malloc(strlen(pChar) + 1);
strcpy(pNewArrayPointer, pChar);
Edit
1) You don't have to copy _inputArr because you don't write data to it in converCharArr().
2) Why are you using sizeof(inputArr)/sizeof(inputArr[0]), it doesn't works, because inputArr is a pointer(well, there are some differences between pointers and arrays :)). You should use arrSize.
Array and pointer differences : http://www.geeksforgeeks.org/g-fact-5/
In your example both prt1 as well as ptr2 are pointing to same char. And you can get same effects for ptr1/ptr2 using cout what you get for arr1.
So, below all will print same thing:-
cout << arr1;
cout << ptr1;
cout << ptr2;
If you want to create new array using ptr2 with same contents as of arr1, then
ptr2 = malloc(strlen(ptr1) + 1);
strcpy(ptr2, ptr1);
May this would help
link: http://ideone.com/Nwqd22
#include <iostream>
using namespace std;
char* fun(){
char * returnValue = "String";
return returnValue;
}
int main() {
char * firstVariable;
firstVariable = fun();
cout << firstVariable;
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm writing a program of a stock market where I read from a file and sort with symbols and percent gain/loss. I have completed sorting with symbols but having trouble establishing the percent gain loss. Basically i am instructed to use vectors. We are required to produce the list ordered by percent gain/loss and i need to sort the stock list by this component. However i'm not to physically sort the list by component percent gain/loss; instead provide a logical ordering with respect to this component.
so basically i added a data member, a vector to hold the indices of the stock list ordered by the component percent gain/loss. i called it array indexByGain. so when i print the list ordered by the percent gain/loss, i use the array indexByGain to print the list. my problem is an i need help on how to start if someone could show me an example or explain on how to go about this i can continue or correct me on my rough draft that will be helpful. below is a rough draft of my code. stockType has to do with the where data is stored from the file.
#include <iostream>
#include "stockType.h"
class stockListType
{
public:
void sortBySymbols();//sort out symbols and it comiples correctly.
void sortByGain();
void printByGain();
void insert(const stockType& item);
private:
vector<int> indexByGain;//declared a vector array indexByGain..
vector<stockType> list;
};
void stockListType::insert(const stockType& item)
{
list.push_back(item)//inserts the data from file to vector array.
}
//function prints out the gain
void stockListType::printByGain()
{
//my code to print out the gain..
}
//function to sort the gain and this is where i am stuck.
void stockListType::sortGain()
{
int i, j, min, maxindex;
for(i=0;i<list.size();i++)
{
min = i;
for(j=i+1;j<list.size();j++)
list[maxindex].getPercentage()<list[j].getPercentage();
maxindex = j;
indexGain.push_back(maxindex);
}
I know I am wrong but am i starting on a good base or totally of. please you could assist me or correct me. Thanks. oh sorry before i forget getPercentage() calculates and returns the percentage gain/loss.
Initialize the index and use std::sort:
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
struct Data {
int value;
int percent;
};
typedef std::vector<Data> DataVector;
typedef DataVector::size_type size_type;
typedef std::vector<size_type> IndexVector;
DataVector data { { 1, 1 }, { 2, -2 }, { 3, 3 }, { 4, -4 }, { 5, 5} };
IndexVector index;
index.resize(data.size());
for(size_type i = 0; i < data.size(); ++i) {
index[i] = i;
}
struct Less
{
const DataVector& data;
Less(const DataVector& data)
: data(data)
{}
bool operator () (size_type a, size_type b) {
return data[a].percent < data[b].percent;
}
};
std::sort(index.begin(), index.end(), Less(data));
for(size_type i = 0; i < index.size(); ++i) {
std::cout << data[index[i]].value << ": " << data[index[i]].percent << std::endl;
}
}
You may use C++11:
std::sort(index.begin(), index.end(),
[&](size_type a, size_type b) { return data[a].percent < data[b].percent; }
);
for(auto i: index)
std::cout << data[i].value << ": " << data[i].percent << std::endl;