How to make pointers to chars in the second array - c++

I have an array of chars. n is array's length
char tab[n];
cin.get(tab, n);
cout<<tab<<"\0"<<endl;
then I create second array
char* t = new char[n];
for(int i = 0; tab[i] != '\0'; i++){
t[i] = tab[i];
}
I would like to have pointers to corresponding element. I mean t[2] contains addres of tab[2]. Then I would like to sort array t so tab stays as it was and only t shuffles but when I make change in the array t for example
t[2] = 'a';
I loose t[3]t[4]....
EDIT:
do{
for(int i = 0; i < n -1; i++){
if(t[i] > t[i+1]){
char* x = &t[i];
t[i] = t[i+1];
t[i+1] = *x
}
n--;
}
}while(n>1);

I would like to have pointers to corresponding element. I mean t2 contains addres of tab2.
So try this:
char** t = new (char*)[n];
for(int i = 0; tab[i] != '\0'; i++){
t[i] = tab+i; // or `&(tab[i])`
To sort the t array based on tab values, use *t[i] to access character values stored in location i of the t array.
See here and here for good tutorials about C pointers.

Related

Memory allocation with looping in C++

I have a List class for char arrays. And I want to push back N arrays from 'a' to 'a..a'.
char* x;
SList list;
for (unsigned int i = 1; i < n+1; i++) {
x = new char[i+1];
for (unsigned int j = 0; j < i; j++) {
x[j] = 'a';
}
x[i] = '\0';
list.push_back(&x);
}
But every time, x has the same address. And in result, my List object contains N pointers to the same address.
Is there a way to push back these arrays in loop with correct memory allocation?
Before asking found this question, but it doesn't provide a cool solution for my problem.
In each iteration of the loop x = new char[i+1]; returns a different address, which is stored in x. So the value of x changes in each iteration, yet, the address of x doesn't.
Did you mean
list.push_back(x);
to add the address of the newly allocated memory? Of course this would require you to change the type of list the a collection of char *.
It must be mentioned that dereferencing &x after x goes out of scope will lead to undefined behaviour, because x doesn't exist anymore. You fill list with dangling pointers.
Finally I'd like to mention that you could avoid the nasty manual memory management and simply use a std::vector<std::string>.
std::vector<std::string> list;
for (unsigned int i = 1; i < n+1; i++) {
std::string newString(i, 'a'); // string with i times 'a'
list.push_back(newString);
}
Ok. I found a pretty straightforward solution:
char** x = new char*[n];
SList sl;
for (unsigned int i = 0; i < n; i++) {
x[i] = new char[i+1];
for (unsigned int j = 0; j < i; j++) {
x[i][j] = 'a';
}
x[i][i] = '\0';
sl.push_back(&x[i]);
}
With having N addresses to store pointers to arrays. I can just add their addresses to my list object

How to create and store string data in multidimensional array?

How can I create and store string data in a multidimensional array using pointers? My attempt is:
// I declaring row 3 and column 2
string** arr = new string*[3][2]; // I am having issue in here
// I am trying to add data
arr[0] = {"first", "second"};
If you want to be able to initialize a whole sub-array like that with {"first", "second"}, you most likely would need to use a std::vector or std::array instead of manually allocating the memory for the array. Unless you have very specific reasons for using pointers, here is how it could look with vectors:
using str_vec = std::vector<std::string>;
std::vector<str_vec> v(3, str_vec(2, ""));
v[0] = {"first", "second"};
But if you really need pointers, then you'll have to first allocate the memory for the "row" and then do separate allocations for each "column":
std::string** a = new std::string*[3];
for(int i = 0; i < 3; ++i) {
a[i] = new std::string[2];
}
After which you can fill the values one by one:
a[0][0] = "first";
a[0][1] = "second";
And don't forget about deleting all these arrays after you are done. In the reverse order, you first need to delete all columns and then the "row":
for(int i = 0; i < 3; ++i) {
delete[] a[i];
}
delete[] a;
There is mistake in the first line of initialization.
Initialize it like this if you want to avoid any error.
string** arr = new string*[3];
/* It will have count of rows of string you will have like in this statement 3 rows of string. */
// Now you will have to tell about columns for each row separately.
for(int i = 0; i < 3; i++) {
arr[i] = new string[2]; // Here you are initializing each row has 2 columns
}
// Now write your code below...
you can rewrite yours code as following :
string **arr = new string*[3]; // row 3
for(unsigned i = 0; i < 3; i++)
arr[i] = new string[2](); // column 2
arr[0][0] = "first"; arr[0][1] = "second";
for(unsigned i = 0; i < 3; i++){. // yours ans
for(unsigned j = 0; j < 2; j++)
cout << arr[i][j] << " ";
cout << '\n';
}

How can I convert vector<string> to char* arr[]?

Recently I want to convert vector to char* array[].
So I had found the solution. But It was not safety way..
Here is my code
char** arr = new char* [4];
vector<string> vv;
// setting strings
for (int i = 0 ;i < 4; i++)
{
vv.emplace_back("hello world");
}
// convert
for (int i = 0; i < 4; i++)
{
arr[i] = new char[vv[i].size()];
memcpy(arr[i], vv[i].c_str(), vv[i].size());
}
// prints
for (int i = 0; i < 4; i++)
{
cout << arr[i] << endl;
}
// output
// hello world羲羲?솎솨
// hello world羲羲拂솽솨
// hello world羲羲
// hello world羲羲?펺솨
// delete memorys
for (unsigned index = 0; index < 4; ++index) {
delete[] arr[index];
}
delete []arr;
Why does it happen string crash??
Is there no safe way anymore?
When you use memcpy, arr[i] is not guaranteed to be a null-terminated string. To treat arr[i] as null terminated string, as in
cout << arr[i] << endl;
causes undefined behavior.
You need couple of minor changes.
Allocate one more byte of memory.
Use strcpy instead of memcpy.
arr[i] = new char[vv[i].size() + 1];
strcpy(arr[i], vv[i].c_str());
There's an easier way of doing this if you can maintain the lifetime of your initial vector.
for (int i = 0; i < 4; i++)
{
arr[i] = vv[i].c_str();
}
This way you won't allocate no additional memory, however, you'd have to keep in mind that once your initial vector gets destroyed, that array will be corrupted as well. But if you need such conversion for some simple synchronous api call within the same thread, that would do the trick.
In such cases I usually use this ugly construct.
arr[i] = new char[vv[i].size() + 1];
arr[i][vv[i].copy(arr[i], vv[i].size())] = 0;

How to delete the last element from array with pointers in C++?

I try to build a function which deletes the last element of an array. So I need an input array and its dimension, then delete the last term and obtain a new output array. I don't want that. My goal is to somehow make the output array the new input array. In other words, I want to overwrite the input array with the output array.
So if dimension is 4, I don't want to have a 4-dim array in the memory but only 3-dim table after the deletion.
void del (int* ptr_array, int dim) {
int* temp = ptr_array; //Hold the very first address of the input array.
ptr_array = new int[dim - 1]; // Let the address of the input array be
// the address of new output array. Overwritting.
for (int i = 0; i < dim - 1; i++) {
ptr_array = (temp+i); // Will it remember what is temp+1 if I have
// already overwritten the arrays?
ptr_array++;
}
//delete[] ptr_array; - this one is out of the questions - deletes now the input table.
}
Can you tell me what is wrong with this code? - in fact it doesn't change anything
in you function
for (int i = 0; i < dim - 1; i++) {
ptr_array = (temp+i); // Will it remember what is temp+1 if I have
// already overwritten the arrays?
ptr_array++;
}
does nothing, you wanted
for (int i = 0; i < dim - 1; i++) {
ptr_array[i] = temp[i];
}
Note the delete in your comment is invalid because you do not delete the result of a new[] but a pointer inside the allocated array
If the call is like
int * v = ...;
del(v);
// here v is unchanged
probably you wanted to modify v, in that case you can return the new array or to use an input-output variable using a reference
First possibility :
int* del (int* ptr_array, int dim) {
int* new_array = new int[dim - 1];
for (int i = 0; i < dim - 1; i++) {
new_array[i] = ptr_array[i];
}
delete[] ptr_array;
return new_array;
}
with
int * v = ...;
v = del(v);
Second possibility
void del (int*& ptr_array, int dim) {
int* new_array = new int[dim - 1];
for (int i = 0; i < dim - 1; i++) {
new_array[i] = ptr_array[i];
}
delete[] ptr_array;
ptr_array = new_array;
}
with
int * v = ...;
del(v);
// here v is the new array
Warning these codes suppose the input array has at least one element
However the use of an std::vector<int> does all of that for you and is more practical to use
std::vector<int> v;
...
v.resize(v.size() - 1);
or
std::vector<int> v;
...
v.pop_back();

How to sort int** array pointing to the int* array elements

I have 2 arrays
int n = 10;
int a[n];
int** t = new int*[n];
then I make that i element of t points to the i element of a
Then I want to sort only pointers in t array
Then I try to bublesort it but it goes wrong
do{
for(int i = 0; i < n -1; i++){
if(*t[i] > *t[i+1]){
char* x = t[i];
t[i] = t[i+1];
t[i+1] = x;
}
n--;
}
}while(n>1);
it's not going through the entire array if you decrement n within the for loop, try placing it outside of the for loop