I want to allocate memory and fill it to the pointer, that are one of the function parameter, but I think that I don't get some important thing, help me please.
So, If I do that everything works fine:
void alloc(char **p, int n)
{
*p = new char[n];
}
int main() {
char * ptr = NULL;
int n = 10;
alloc(&ptr, n);
for(int i = 0; i<(n - 1); i++)
ptr[i] = '1';
ptr[n - 1] = '\0';
printf("%s", ptr);
return 0;
}
Now I want to initialize the allocated memory also into the function
void alloc(char **p, int n)
{
*p = new char[n];
for(int i = 0; i<(n - 1); i++)
*p[i] = '1';
*p[n - 1] = '\0';
}
int main() {
char * ptr = NULL;
int n = 10;
alloc(&ptr, n);
printf("%s", ptr);
return 0;
}
Program crashes. I don't get why. Please, can someone explain?
Try (*p)[i] and (*p)[n - 1] instead. The precedence rules cause *p[i] to be evaluated as *(p[i]).
Try this:
((*p)[i]) = '1';
you have a problem with operator's evaluation order.
Probably because this:
*p[i]
is interpreted as if you had written this:
*(p[i])
not as if you had written this, which is what you probably meant:
(*p)[i]
This should do the trick,
void
alloc( char*& p, int n )
{
p = new char[n];
std::fill_n( p, n - 1, '1' );
p[n - 1] = '\0';
}
If you insist on using a pointer as argument, change all of the p
in the function to (*p) (and don't forget to check for a null pointer
and do something reasonable if you're passed one.
All things considered, however, you'd be better off using
std::string—this function wouldn't even be necessary, as you
could write std::string( n, '1' ).
Try this
#include <stdio.h> // for NULL
void alloc(char **p, int n)
{
*p = new char[n];
for(int i = 0; i<(n - 1); i++)
*((*p) + i) = '1';
*((*p) + n - 1) = '\0';
}
int main() {
char * ptr = NULL;
int n = 10;
alloc(&ptr, n);
printf("%s", ptr);
// never forget delete pointers
delete [] ptr;
return 0;
}
Its a precedence of operators issue. Try this in your alloc function:
for(int i = 0; i<(n - 1); i++)
(*p)[i] = '1';
(*p)[n - 1] = '\0';
Related
void * bubbleSort(void * data){
int * str;
str = (int* ) data;
int temp = 0;
for ( int i = 0 ; i < len ; i++ ){
for (int j = i + 1; j < len ; j++ ){
if(str[i] > str[j]){
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
}
}
int main(){
int *data= new int[1000000];
...
pthread_t thread[input];
for ( int i = 0 ; i < input ; i ++){
pthread_create(&thread[i],NULL,bubbleSort,arguments);
pthread_join(thread[i],NULL);
}
}
I have int *data[1000000] and I want to use pthread to pass parameter to bubble sort.
The above is the code I wrote, but it is no output
How to successfully work ?
To fix your immediate problem: your data variable is defined with the wrong type.
int *data[1000] is an array of 1000 int *, which decays to int**. Your bubbleSort function expects an int *.
Declare data as follows instead:
int * data = new int[10000];
and then you can simply pass it to pthread_create as a void* like you do now.
However, modern C++ has a std::thread which is far easier to work with:
std::thread sorter(bubbleSort, data);
sorter.join();
I'm having a hard time with this little project of mine; can someone help me out? I am trying to take a pointer to an array, a number, and remove the number if it is present in the array. If the number is removed, the array shrinks. Please note at the time of running removeNumber size = 6.
main
{
int size = 5; // setting array size
int *a = new int[size]; // allocating dynamic array
// initializing array
a[0] = 0; a[1] = 10; a[2] = 20; a[3] = 30; a[4] = 40;
removeNumber(a, 10, size);
}
And now the prototype:
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
int *newArray = new int[size - 1];
if (index != -1)
{
for (int i = number; i <= size; ++i)
newArray[i] = *&arrayPtr[i + 1];
delete[] arrayPtr;
arrayPtr = newArray;
size -= 1;
}
}
Check for reference:
int check(int *arrayPtr, int number, int size)
{
for (int i = 0; i < size; i++)
{
if (arrayPtr[i] == number) return i;
}
return -1;
}
The function is wrong. First of all it has a memory leak in case when the target value is not found in the array.
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
int *newArray = new int[size - 1];
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if (index != -1)
{
//...
}
}
Secondly there is used incorrect range of indices
for (int i = number; i <= size; ++i)
^^^^^^ ^^^^^^^^^
newArray[i] = *&arrayPtr[i + 1];
^^^^^^
And you could write this expression *&arrayPtr[i + 1] simpler just like arrayPtr[i + 1].
You forgot to copy the elements of the original array before the index index. number is not a valid index.
Also it would be better if the function returned a Boolean value saying whether the operation was successful or not. You can change the size of the array in the calling function if the call was successful.
So I would write the function like
bool removeNumber( int * &arrayPtr, int n, int value )
{
int index = check( arrayPtr, number, size );
if ( index != -1 )
{
int *tmp = new int[size - 1];
int i = 0;
for ( ; i < index; ++i ) tmp[i] = arrayPtr[i];
for ( ; i < size - 1; i++ ) tmp[i] = arrayPtr[i+1];
delete [] arrayPtr;
arrayPtr = tmp;
}
return index != -1;
}
It is ok to reinvent the wheel in order to learn. However you should be aware of the standard way to handle this: using std::vector along with std::remove/std::remove_if (defined in #include <algorithm>) would make your life much simpler, with the benefit of a performant implementation.
void removeNumber(std::vector<int>& vec, int number) {
vec.erase(std::remove(std::begin(vec), std::end(vec), number),
std::end(vec));
// If you really want to shrink the vector, you can call...
vec.shrink_to_fit();
}
I also made a little demo to show you that it works as intended.
Your problem is here:
for (int i = number; i <= size; ++i)
First of all you start the iteration from the value of the number that you searched(in your case 10) and as a result you will not enter the for loop.So the correct starting value of i is the first number of the array which is 0.Then this line of code here:
newArray[i] = *&arrayPtr[i + 1];
doesn't even make sense(as a thought process not syntactically), but what i think you want to do here is just copy the correct element from the old array to the new one.
A correct implementation of the previous is the following code:
void removeNumber(int *& arrayPtr, int number, int &size)
{
int index = check(arrayPtr, number, size);
if (index != -1)
{
int *newArray = new int[size - 1];
int i = 0,j=0; //i for the old array and j for the new
while(i < size)//while we are in bounds
{
if(i==index)//if the index is the index of the given element
{ //skip this number
i++;
continue;
}
newArray[j++] = arrayPtr[i++];//copy the correct number to the correct position
}
delete[] arrayPtr;
arrayPtr = newArray;
size -= 1;
}
}
Well consider this:
int * hello = new int[10];
for (register int i = 0; i < 10; i++)
*(hello + i) = i;
int * & hello_ref = hello;
delete[] hello_ref ;
for (register int i = 0; i < 10; i++)
cout << *(hello + i) << std::endl;
Nowhello_ref can succesfully delete the memory which is allocated by new ... From a fact that the reference and pointer are very close how we do the same thing with pointer to pointer to new memory allocated
now consider this
int i = 0;
unsigned int * hello = new unsigned int[6];
for (register int i = 0; i < 6; i++)
*(hello + i) = i;
unsigned int * bye = new unsigned int[4];
for (register int i = 0; i < 4; i++)
*(bye + i) = i;
unsigned int ** del = new unsigned int *[2];
*del = bye;
*(del + 1) = hello;
delete[] * del;
delete[] * (del + 1);
Is there any way that we could delete the new allocated memory for hello and bye with the del pointer to pointer ... these could just clear the data which hello and bye pointed to ....
You just need to delete the array referenced by del:
delete[] del;
You are already deleting the arrays referenced by hello and bye:
delete[] * del;
delete[] * (del + 1);
Though this would be more idiomatic:
delete[] del[0];
delete[] del[1];
Or even better, avoid using new and delete altogether, taking advantage of modern C++ features. What you are writing looks more like C.
#include <array>
#include <numeric>
#include <tuple>
template<typename T, std::size_t N>
std::array<T, N> make_increasing_array(T initial = T())
{
std::array<T, N> array;
std::iota(array.begin(), array.end(), initial);
return array;
}
int main()
{
auto del = std::make_tuple(
make_increasing_array<unsigned int, 6>(),
make_increasing_array<unsigned int, 4>());
auto& hello = std::get<0>(del);
auto& bye = std::get<1>(del);
}
If I understand your question correctly then the answer on the 1st part of your question will be something like this:
...
int * * hello_ref = &hello;
delete[] *hello_ref;
...
About second part, you did exactly what you asked. Those 2 delete do the job. Just add delete[] del; as a final touch.
I've this piece of code which is working by now(at least):
int** constructSparseMatrix(int totalRow, int totalCol, int totalEl) {
int** arr = new int*[totalEl];
//int x = 0;
for(int i = 0; i < totalEl; i++) {
arr[i] = new int[totalCol];
for (int k = 0; k < totalCol; k++) {
if(k == totalCol - 1) {
arr[i][totalCol - 1] = rand () % 101;
} else {
arr[i][k] = rand () % totalRow + 1;
}
}
}
return arr;
}
and I'm trying to access the element inside by using pointer instead of array and here is my try:
int** constructSparseMatrix(int *totalRow, int *totalCol, int totalEl) {
int** arr = new int*[totalEl];
//int x = 0;
for(int i = 0; i < totalEl; i++) {
arr[i] = &totalCol [0];
for (int k = 0; k < *totalCol; k++) {
if(k == *totalCol - 1) {
arr[i][*totalCol - 1] = rand () % 101;
} else {
arr[i][k] = rand () % *totalRow + 1;
}
}
}
return arr;
}
But when I initialize the same way as the working function:
int** arr = constructSparseMatrix(5,3,totalEl);
then I receive this error:
argument of type "int" is incompatible with parameter of type "int *"
First of all, is my conversion from array to pointer version coded properly? If it's correct, how can I initialize it to avoid above error?
First of all it is obvious that this statement in the function
arr[i] = &totalCol [0];
is wrong. It does not make sense.
You declared the function
int** constructSparseMatrix(int *totalRow, int *totalCol, int totalEl);
as having the first and second parameters as pointers but are trying to pass integer literals 5 and 3 to it in the call
int** arr = constructSparseMatrix(5,3,totalEl);
You could write for example
int totalRow = 5;
int totalCol = 3;
//...
int** arr = constructSparseMatrix( &totalRow, &totalCol, totalEl );
But I do not see a sense to declare these parameters like pointers because they are in fact constants within the function that is they are not changed.
And the variable names confuse the reader. For example I would expect that totalRow is used within the function in statement
int** arr = new int*[totalRow];
instead of totalEl
If you want to use pointers within the function then the function can look like
int** constructSparseMatrix( int totalRow, int totalCol, int totalEl )
{
int** arr = new int*[totalEl];
for ( int **p = arr; p < arr + totalEl; ++p )
{
*p = new int[totalCol];
for ( int *q = *p; q < *p + totalCol; ++q )
{
if ( q == *p + totalCol - 1 )
{
*q = rand () % 101;
}
else
{
*q = rand () % totalRow + 1;
}
}
}
return arr;
}
I think you are passing constants 5 and 3 as arguments which causes this error.
you can't pass constant value as it is by reference.Try passing 5 and 3 by storing them in a variable.
Input :
A[4] = {0,4,-1,1000} - Actual Array
P[4] = {1,0,3,2} - Order to be reshuffled
Output:
A[4] = {4,0,1000,-1}
Condition : Don't use an additional array as memory. Can use an extra variable or two.
Problem : I have the below program in C++, but this fails for certain inputs of array P.
#include<iostream>
using namespace std;
void swap(int *a_r,int *r)
{
int temp = *r;
*r = *a_r;
*a_r = temp;
}
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0] , dest = P[0];
for(int i=0; i<4;i++)
{
swap(&A[dest],&value);
dest = P[dest];
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
}
Since you've got a spare array called P kicking around, and there isn't anything in the question as quoted that stipulates it must be treated as a constant array, you could do:
for (i = 0; i < 4; i++)
P[i] = A[P[i]];
for (i = 0; i < 4; i++)
A[i] = P[i];
If you're not allowed to modify P, then you have to work a lot harder (and you also have to work a lot harder if the data type of A is not the same as, or compatible with, the type of P).
However, I fear this is a sleight-of-hand trick that doesn't really answer the question; it gets the job done, but doesn't answer the question.
First of all, I really like Jonathan's solution, but I feel like I can add some interesting ideas too.
The main observation is that array P consists of several loops.
Let's consider p = {1, 4, 3, 2, 0, 5}. There're three loops: 0 => 1 => 4 => 0, 2 => 3 => 2 and 5 => 5. And to replace variables alongside one loop we need no additional memory at all. We just go through it like this
do {
a[i] = a[p[i]];
i = p[i];
} while (i != first_i);
(The last element needs to be taken special care of, though.) The full working version:
for (int i = 0; i < n; ++i) {
if (p[i] < 0) {
// been at index 'i' already
continue;
}
// new loop found
int j = i;
int first_value = a[i]; // to be put in last position in the chain
int prev_j; // we always store previous 'j' index
do {
a[j] = a[p[j]];
prev_j = j;
j = p[j]; // move to next 'j'
p[prev_j] = -1; // mark element as processed
} while (i != j);
a[prev_j] = first_value;
}
The only problem with my solution is that it uses p array to mark element as 'processed'. Some interviewers may consider it ok, others - not, depending on the solution they have in mind.
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
A[4] = {0,4,-1,1000}
P[4] = {1,0,3,2}
int temp = arr2[0];
for(int i=0;i<4;i++)
{
for(temp = P[i];i<3;temp = P[temp])
{
if(temp >= i)
{
int data;
data = A[i];
A[i] = A[temp];
A[temp] = data;
break;
}
}
}
_getch();
return 1;
}
Slightly modified to calculate dest value
int main()
{
int A[4] = {0,4,-1,1000};
int P[4] = {3,0,1,2};
int value = A[0], dest = P[0];
for(int i=0; i<4-1;i++)
{
int count=0;
dest = P[i];
while(dest<i){ //if P[i] points to lower value, it got swapped with some other position.
dest = P[dest];
}
swap(&A[dest],&A[i]);
}
for(int i=0;i<4;i++)
cout<<A[i]<<" ";
cout<<"\n";
}
Could argue that it goes against the spirit of the question - but can use multiple stack instances (from a run-time perspective) of a single local variable (code perspective). Being allowed to mutate P is just as uncertain, so, FWIW - a recursive answer...
template <int N>
void shuffle(int (&a)[N], int p[], int i = -1)
{
if (++i < N)
{
int result = a[p[i]];
shuffle(a, p, i);
a[i] = result;
}
}