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;
}
Related
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
}
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 4 years ago.
Improve this question
I'm having troubles dealing with pointer when it comes to using another library function
The library has a void function where it modifies a long value by reference successfully, but when trying to modify the value of a char*, the memory allocation from the library gets lost when the function ends, leaving me with unable to read memory.
I don't know what the size of the char* the function will create, so I can't allocate memory before it.
Any help?
EDIT1: posting some code example
EDIT2: posted 2 solutions
Main program:
char* resizedPixels = new char[2]; // random number to initialize it
long pixelsSizeRed;
//calling the method from another library
ImageResizer::reziseImg("C:\img.jpg", &resizedPixels, pixelsSizeRef);
// end of main program
on the library side, the function is as follows:
void resizeImg(char* inputPath, char** resizedPixels, long &pixelsSize){
pixelsSize=100; //calculated with other methods, hands out the value correctly
//now that I have the size, allocate memory on the char array I need
*resizedPixels = new char[pixelsSize];
//modify inputPath bytes, and passing them to resizedPixels
char* buffer = "something manipulated";
for (int i = 0; i < pixelsSize; ++i) {
(*resizedPixels)[i] = buffer[i];
}
}
Solution 2: using vectors
void resizeImg(vector<char>&, long );
int main() {
vector<char> pixelVec;
char* resizedPixels;
long pixelsSizeRef;
resizeImg(pixelVec, pixelsSizeRef);
// for loop to pass value
resizedPixels=new char[pixelsSizeRef];
for(int i=0; i<pixelsSizeRef; i++){
resizedPixels[i]=pixelVec.at(i);
}
//our char* has the values from library's function
return 0;
}
void resizeImg(vector<char> &myVec, long pixelSize) {
// modify your string
pixelSize=10;
char foo[pixelSize] = "abcdefghi";
for (int i = 0; i < 10; ++i) {
myVec.push_back(foo[i]);
}
}
The reason the value is lost is because you try to modify a pointer in a function by passing it by value (you pass a char*). You need to pass it by pointer (so a char**) if you want to modify it within the function and have that modification reflected outside of it.
Think about it the same way you would think about a function which is supposed to modify an int. You would need to pass a pointer on the integer (a int*) for the modification to be reflected outside the function. Here, you pass your char* by value, so that in the function, there is a different object of type char* that is constructed, and on which all your manipulation are done. Once you exit the function, that object on which everything has been done is destructed, and you never actually touched the object in the caller block that you wanted to modify in the first place.
I wrote a minimal functioning code of a function that modify a char* which you can use as an example if you want to modify accordingly your code (put it in a .cpp file and run it) :
#include <iostream>
void resizeImg(char** myarray);
int main() {
char* resizedPixels;
resizedPixels = new char[5];
for (int i = 0; i < 4; ++i) {
resizedPixels[i] = i + 65;
}
resizedPixels[4] = '\0';
std::cout << resizedPixels << std::endl;
resizeImg(&resizedPixels);
std::cout << resizedPixels << std::endl;
return 0;
}
void resizeImg(char** myarray) {
// allocate memory for your string
// (you can do that with your pixelSize,
// don't forget that the last char is '\0')
*myarray = new char[10];
// modify your string
char foo[10] = "abcdefghi";
for (int i = 0; i < 10; ++i) {
(*myarray)[i] = foo[i];
}
}
The output is :
ABCD
abcdefghi
Here, the char* is passed by pointer, so that the prototype of the function takes a char**. And it actually modifies the string from the caller block.
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
I am trying to build a dynamic array of objects using pointers arithmetic. However, the compiler return the following error in this line in the main.cpp
(*(lista+n))(id1,seleccion1,edad1,camiseta1);
error: no match for call to '(jugador) (int &, int & short, short int &, short int &)'
any suggestion is welcome, thanks.
This is the class.
class jugador
{
private:
int id;
short seleccion;
short edad;
short camiseta;
public:
jugador();
jugador(int ID, short SELECCION, short EDAD, short CAMISETA);
int obtener_id();
short obtener_seleccion();
short obtener_edad();
short obtener_camiseta();
void cambiar_id(int nueva_id);
void cambiar_seleccion(short nueva_seleccion);
void cambiar_edad(short nueva_edad);
void cambiar_camiseta(short nueva_edad);
void cambiar_todo(int nueva_ID, short nueva_SELECCION, short nueva_EDAD, short nueva_CAMISETA);
void mostrar_jugador();
};
The constructors...
jugador::jugador()
{
id=999999;
seleccion=32;
edad=99;
camiseta=99;
}
jugador::jugador(int ID, short SELECCION, short EDAD, short CAMISETA)
{
id=ID;
seleccion=SELECCION;
edad=EDAD;
camiseta=CAMISETA;
}
Here is the full code.
Is there a special reason you are not using std::vector<jugador> Check this thread for the advantages of replacing realloc with vector
You have not given enough information so here is what I can tell from the looks of the error:
(*(lista+n))(id1,seleccion1,edad1,camiseta1);
that is NOT a function pointer, it's not even pointing to a function in the first place.
It seems like you are trying to construct an array of jugador by moving the lista pointer. If that is what you want to do then you can do late initialization.
jugador * lista; //< unitialized pointer
int n = 11; //< your number of players, lets suppose 11
lista = new jugador[11]; // now you have an array of jugadores
for(int i = 0; i != n; ++i)
{
lista[i] = jugador(id1,seleccion1,edad1,camiseta1);
}
// use your jugadores, let's suppose you want to use the tenth jugador
jugador *iterator = lista;
iterator+10;
use(*iterator); //*iterator variable holds your 10th jugador object
delete[] lista;
You are using realloc in your code, I suggest you try new and delete instead. Or else provide an explanation of why using realloc is a good choice.
Another thing I noticed in your code is that you don't free the memory you are using. Thus you have a memory leak.
If you need more jugador the use std::copy to achieve that
// let's say in this point you need 20 jugador more
jugador * newlista = new jugador[n+20];
std::copy(lista, lista+11, newlista);
delete[] lista; //you delete the old buffer
for(int i = 11; i != n+20; ++i)
{
newlista[i] = jugador(id1,seleccion1,edad1,camiseta1);
}
// and now newlista has your jugadores, you can even make a function that does that
delete[] newlista ; // delete your jugadores
I am completely agreed with Claudiordgz's response. However, if you want to call the constructor with parameters (without making extra copies) you will need to make an array of pointers instead of an array of objects. I am pasting a version of your code with that. However, I still think that a version using vectors is safer and superior.
Code:
int main()
{
int id1;
short seleccion1, edad1, camiseta1;
jugador arreglo[5];
int n = 0, i;
char opcion = 's';
jugador **lista=NULL;
while (opcion == 's')
{
lista = new jugador*[n];
cout<<"id: "<<endl;
cin>>id1;
cout<<"Seleccion: "<<endl;
cin>>seleccion1;
cout<<"Edad: "<<endl;
cin>>edad1;
cout<<"Camiseta: "<<endl;
cin>>camiseta1;
lista[n] = new jugador(id1,seleccion1,edad1,camiseta1);
n++;
cout << "Desea ingresar otro elemento? (s/n): ";
cin >> opcion;
}
cout << "\nArreglo completo\n";
for (i=0; i<n; i++)
{
lista[n].mostrar_jugador();
}
//deallocating memory
for (int i=0; i<n; i++)
{
delete jugador[i];
}
delete [] jugador;
return 0;
}
i am starting homework about dynamic array, first, I have a 2 dimensional array :
int initializeInfo[3][4] ={{77,68,0,0},{96,87,89,78},{70,90,86,0}};
and use pointer to store it:
int **ptr = (int**)malloc(3*sizeof(int));
int size = 0;
for(int i =0;i<3;i++){
addInitiazeInfo(ptr,initializeInfo[i],size);
}
here is function addInitiazeInfo:
void addInitiazeInfo(int**& ptr, int arr[],int& size){
ptr[size] = (int*)malloc(4*sizeof(int));
if(ptr[size] == NULL){
return;
}
ptr[size] = arr;
size++;
}
It's run OK! The 2 dimensional array is store by ptr pointer.
And I want to add new row, I think realloc is needed, then I try:
int arr[] = {3,4,5,6};
size++;
ptr = (int**)realloc(ptr,size * sizeof( int ) );
ptr[size-1] = (int*)malloc(4*sizeof(int));
ptr[size-1] = arr;
But I think this is my trouble, the output make me hard to know how it happend:
please help me, thanks everyone
When you do
ptr[size] = arr;
You are essentially assigning the address of arr, to ptr[size]. This means that the memory you just allocated is lost and successfully leaked.
You want to manually copy element by element or use something like memcpy. It is likely this might fix your issue, depending on the rest of your code.