gdb - how to view contents of an array of pointer? - c++

I am having a problem in getting the contents of the variable 'arr' which is an array of pointers.
I tried,p *arr#n, but it gives the following output: $1 = {0x603010, 0x603030}.
What should I do?
int n, q;
scanf("%d %d", &n, &q);
int lastAnswer=0, index_size[n], *arr[n]; // <-- here
for(int i=0; i<n; i++)
index_size[i] = 0;
for(int i=0; i<n; i++) {
int *temp = malloc(sizeof(int)*n);
arr[i] = temp;
}
while(q--) {
int w, x, y, seq;
scanf("%d %d %d", &w, &x, &y);
if(w == 1) {
seq = ((x ^ lastAnswer) % n);
arr[seq][index_size[seq]++] = y;
}
else {
seq = ((x ^ lastAnswer) % n);
lastAnswer = y%n;
printf("%d\n", lastAnswer);
}
}
return 0;

If you print out a pointer itself, it would just give you an address in your memory block.
So print *arr#n would simply give you the content of the first dimension (an array of address in your output)
If you want to print out the deeper content. You might want to do something like this:
print **arr#n;
or
print *arr[0]#n
Another method would be define a pretty print function inside your program and call it in gdb.
void print(int arr[][], n, m)
{
int i, j;
for (i = 0; i < n; ++i)
{
for (j = 0; j < m; ++j)
printf("%d ", arr[i][j]);
printf("\n");
}
}
And call it in gdb by
call print(arr, n, m)
I don't think gdb support printing 2D array itself, why?
Because the definition of print *array#3 isn't printing the first three elements in array, instead, it is "priting *array (or array[0]) and the three elements following array[0].
print **arr#n#n
would not work in this case, (although it print out an nice format)

Related

invalid type argument of unary '*' (have 'int') lowest element in array

I want to find the lowest element in the array using a function lowest(). But this program does not work. It shows the error
invalid type argument of unary '*' (have 'int')
Here is the code:
#include <stdio.h>
int lowest(int *j, int n) { //For finding the lowest element
int i, temp, tempAdd;
for (i = 0; i < n; i++) {
if (temp > *(j + i))
temp = *(j + i);
tempAdd = j + i;
}
return tempAdd; //Sends the address of the lowest element
}
int main() {
int n;
printf("Enter the number of inputs: ");
scanf("%d", &n);
int arr[n], i;
for (i = 0; i < n; i++) {
printf("\nEnter element no. %d: ", i + 1);
scanf("%d", &arr[i]);
}
for (i = 0; i < n; i++) {
printf("Element no. %d is %d with the address %d.\n", i + 1, *(arr + i), arr + i);
}
int low = lowest(arr, n); //Saves the address of the lowest element.
printf("\nThe Lowest element in the list is %d with address %d.", *low, low); //Error occurs
return 0;
}
Your function lowest has problems:
int lowest(int *j, int n) { //For finding the lowest element
int i, temp, tempAdd;
for(i = 0; i < n; i++) {
if(temp > *(j + i))
temp = *(j + i);
tempAdd = j + i;
}
return tempAdd; //Sends the address of the lowest element
}
you forgot the braces around the if block. Indentation does not determine block structure in C.
the semantics are inconsistent: you return the index to the lowest element but you set tempAdd to j + i which is a pointer to the lowest element.
you do not initialize temp, nor tempAdd. The behavior is undefined.
it is confusing to name a pointer j, j is usually designates an integer index. Use p.
Here is a simpler version:
int lowest(int *p, int n) { //For finding the lowest element
int i, tempAdd = 0;
for (i = 1; i < n; i++) {
if (p[i] < p[tempAdd]) {
tempAdd = i;
}
}
//Return the index of the lowest element
return tempAdd;
}
In main, you should modify the code because low is not a pointer:
printf("\nThe Lowest element in the list is %d with address %d.",
arr[low], &arr[low]);
For printing address you can use %p as below.
printf("\nThe Lowest element in the list is %d with address %p.", low, low);
#include<stdio.h>
int *lowest(int *j, int n) { //For finding the lowest element
int i, temp;
int *tempAdd;
temp=*j;
tempAdd=j;
for(i = 0; i < n; i++) {
if(temp > *(j + i)){
temp = *(j + i);
tempAdd = j + i;
}
}
return tempAdd; //Sends the address of the lowest element
}
Along with this correct the following line
int low = lowest(arr, n); to int *low = lowest(arr, n);
the lowest function should be:
int *lowest(int *j, int n) { //For finding the lowest element
int i, temp = *j;
int *tempAdd = NULL;
for(i = 0; i < n; i++) {
if(temp > *(j + i))
temp = *(j + i);
tempAdd = j + i;
}
return tempAdd; //Sends the address of the lowest element
}
and in your main function: use int *low instead of int low and use %p to display the variable address.
Here the first iteration of a fixed function. It still is not 100% as I would write it but restricts itself to address the problem of the question.
As you want to return the address, I adjusted the return type as well as the type of variable tempAdd
int* lowest(int *j, int n) { //For finding the lowest element
int i, temp;
int *tempAdd;
for(i = 0; i < n; i++) {
if(temp > *(j + i)) {
temp = *(j + i);
tempAdd = j + i;
}
}
return tempAdd; //Sends the address of the lowest element
}
E.g., for parameter n = 0 the return value of your function would be undefined if no further changes to the function are made.
As variable temp is also not initially initialized, it is also possible that the address returned is undefined in case, that no member of the array is smaller than the (random) value of variable temp.
Here, a slightly more robust version:
int* lowest(int *j, int n) { //For finding the lowest element
if( 0 == n ) return NULL; // empty arrays have no smallest element!
int i;
int temp = j[0]; // instead of using pointer arithmetic you can also use this syntax.
int *tempAdd = j; // initially the first element is allegedly the smallest...
for(i = 1; i < n; i++) // loop starts at index 1 now!
{
if(temp > *(j + i)) {
temp = *(j + i);
tempAdd = j + i;
}
}
return tempAdd; //Sends the address of the lowest element
}
Your function main() also has its issues. You cannot create an automatic (stack-located) array of dynamic size, which is what you try. Instead, if you want to query the user for the size of the array, you would have to resort to a heap-based array, instead. Or you would query for a size, which is smaller or equal an arbitrary chosen fixed size of your stack based array.
int main() {
int n = 0;
printf("Enter the number of inputs (1..500): ");
scanf("%d", &n);
if( n < 1 || n > 500 ) {
puts("Invalid input.");
return -1;
}
int arr[500]; // 500 was chosen because most likely no one is crazy enough to manually type in more values by hand ;)
int i;
for(i = 0; i < n; i++) {
printf("\nEnter element no. %d: ", i + 1);
scanf("%d", &arr[i]);
}
for(i = 0; i < n; i++) {
printf("Element no. %d is %d with the address %d.\n", i + 1, *(arr + i), arr + i);
}
int * low = lowest(arr, n); //Saves the address of the lowest element.
printf("\nThe Lowest element in the list is %d with address %p.", *low, low); //Error occurs
return 0;
}
Also changed the formatting to "%p" for pointer.
Also changed type of low from int to int *.
Last not least you would have to change main() further, if you were to allow 0 array size. Why? Because in your printf you write ...,*low,.... As lowest() would return NULL in the case of n = 0, you would dereference a NULL pointer, which leads to a nasty run time error.
From a design perspective, eventually, returning the address in lowest() appears to break the level of abstraction, related to the fact that you pass in the length of the array. You mix two styles, basically.
STL- style would be: int * lowest( int *begin, int * end )
Vintage- style would be: int lowestIndex( int *arr, int n)
The second version, though would have the problem that you cannot express a "no result" outcome. E.g if Array size is 0 or other invalid arguments are being passed to the function. Thus, often people would do it this way instead:
bool lowestIndex( int * arr, int n, int *result )
... where the return value indicates success and the result content is only valid if the return value was true.

Can't get my pointers to send a reference to the array

#include<stdio.h>
#include<stdlib.h>
int* getEvenNumbers(int arr[], int N)
{
int i, k = 0 , a[50], p;
for (i = 0; i < N; i++)
{
if (arr[i] % 2 == 0)
{
arr[k]=arr[i];
k++;
}
}
return arr[k];
}
int main ()
{
int i, arr[5000000], N, a[500000], k, *p;
printf("\nEnter your desired length of the array:\n\n");
scanf("%d", &N);
for (i = 0; i < N; i++)
arr[i]= rand();
getEvenNumbers (arr, N);
printf("\n\nEven numbers in the array are as follows:\n\n");
for (i = 0; i < N; i++)
{
a[i]= *(p+i);
printf("\n[%d] = %d", (i+1), a[i]);
}
}
please i know this is probably very easy for you guys but i need help figuring out how to return a pointer to the array without all my values of my array getting deleted, also i can't use global variables and it has to be a function that returns a pointer pointing to the array
First of all, decrease the size of those arrays, you don't need that much space. Second of all, you made your
getEvenNumbers
function return an int *, and not an int. arr[k] is not an int *. I also don't get why you are returning something if nothing is being assigned when you call the function. You can just change the return type to void.
void getEvenNumbers(int arr[], int N)
You also never allocate any memory for p. You can do
p = (int*) malloc(sizeof(int));
And since you never allocated any memory for p, the following line of code
a[i]= *(p+i);
is assigning a[i] to a random address. You should just try to rewrite this program. There a lot of errors in this program that I didn't even correct. Go on Google an look up finding even numbers in array program or something similar and look at the code of those examples.
EDIT:
I found some code examples for you to use. I hope it helps!
StackOverflow
sanfoundry.com
The caller already knows the address of the array, so you just need to return the new length. If we also remove the unused variables and take advantage of C++ declarations, we will have:
int getEvenNumbers(int* arr, int N)
{
for (int i = 0, k = 0; i < N; i++) {
if (arr[i] & 1 == 0) { // even if lowest bit is zero
arr[k] = arr[i];
k++;
}
}
return k;
}
Now you can print the even numbers easily:
int k = getEvenNumbers(arr, N);
printf("\n\nEven numbers in the array are as follows:\n\n");
for (i = 0; i < k; i++) {
printf("\n[%d] = %d", (i+1), arr[i]);
}
Dynamically allocate memory from heap.
int* a= new int [N];
//Now store the elements from index 1.
// at a[0] store the number of even number you have found in this function.
return a;
In main you know how many even numbers are there.
int *a1=getEvenNumbers(arr,n);
count_even=a1[0];
for(index=1;index<=count_even;index++)
cout<<a1[index];
The code is given here-
#include<stdio.h>
#include<stdlib.h>
int* getEvenNumbers(int arr[], int N)
{
int i, k = 1 , p;
int* a=new int[N+1];
for (i = 0; i < N; i++)
{
if (arr[i] % 2 == 0)
a[k++]=arr[i];
}
a[0]=k-1;
return a;
}
int main ()
{
int i, N;
printf("\nEnter your desired length of the array:\n\n");
scanf("%d", &N);
int arr[N];
for (i = 0; i < N; i++)
arr[i]= rand();
int *a=getEvenNumbers (arr, N);
printf("\n\nEven numbers in the array are as follows:\n\n");
for (i = 1; i <= a[0]; i++)
printf("\n[%d] = %d", (i), a[i]);
delete []a;
}
A better option is to use std::vector.You can read it here.

Shifting array to replace removed element

I am supposed to get the output 8, 6. But I get 8,9 when this code is run. Why am I getting the out put 8,6 and how can I fix the code to make the output become 8,9.
int inputarray[]={9,8,9,9,9,9,6};
int length = 7;
int value = 9;
void arrayShift(int arr[], int length, int value)
{
for(int i = 0; i<length; i++)
{
if(arr[i] == value)
{
for (int k = i; k<length ; k++)
{
arr[k] = arr[k+1];
}
arr[length-1] = 0;
}
}
}
When shifting array, you may replace first element (containing number equal to value) with the same value from other element. In that case, you need to restart iteration on this element again, e.g.:
void arrayShift(int arr[], int length, int value)
{
for(int i = 0; i<length; i++)
{
if(arr[i] == value)
{
for (int k = i; k<length-1 ; k++)
{
arr[k] = arr[k+1];
}
arr[length-1] = 0;
i--; // <-- this
}
}
}
Your algorithm for shifting is wrong: you fail to adjust i on removal. In addition, it is rather inefficient: you can do this in a single loop with two indexes - r for reading and w for writing. When you see the value you want to keep, adjust both the reading and the writing index. Otherwise, increment only the reading index.
Once the reading index reaches the count, the writing index indicates how many items you have left. You need to return it to the caller somehow, otherwise he wouldn't know where the actual data ends. You can return the new length as the return value of your function, or take length as a pointer, and adjust it in place.
int arrayShift(int arr[], int length, int value) {
int r = 0, w = 0;
for (; r != length ; r++) {
if (arr[r] != value) {
arr[w++] = arr[r];
}
}
return w;
}
Here is how you call it:
int inputarray[]={9,8,9,9,9,9,6};
int length = 7;
int value = 9;
int newLen = arrayShift(inputarray, length, value);
for (int i = 0 ; i != newLen ; i++) {
printf("%d ", inputarray[i]);
}
printf("\n");
Demo.

arrays not being assigned properly

void sort(int* A,int l)
{
int j;
int B[l];
for(int i=0;i<l;i++)
{
j = largest(A,l);
B[l-i-1] = A[j];
A[j] = -1;
}
A = B;
}
int main()
{
.
int C[3] = {x,y,z};
...
sort(C,3);
cout<<C[0]<<C[1];
}
output is coming to be -1-1
But if we assign A[0] = B[0] and so on, then we are getting the right answer.
PS: I've tried using *A = *B, which is only giving the first element to be correct.
When you assign A = B, you re-assign a local variable that holds a pointer to the first element of your array. This assignment will not change anything in main. In particular, the contents of A will not be affected.
You must copy all the elements from B to A after you have finished your sorting:
void sort(int *A, int l)
{
int j;
int B[l];
// sort into temporary array B
for (int i = 0; i < l; i++) {
j = largest(A, l);
B[l - i - 1] = A[j];
A[j] = -1;
}
// copy temporary array B to result array A
for (int i = 0; i < l; i++) A[i] = B[i];
}
But if you look at it, Amol Bavannavar was basically right: You don't have to check the whole array for the largest element each time. It is enough to check the remaining elements. So instead of assigning a low value to "used" elements, you could swap the largest elements to the end. When you do that, you'll see that the processed elements are at the end, the unprocessed elements are at the beginning. Then you can do your sorting in place without the need of a temporary array:
void sort2(int *A, int l)
{
while (l) {
int j = largest(A, l--);
int swap = A[j]; A[j] = A[l]; A[l] = swap;
}
}
There are many wrong uses of code in your example, for instance:
int B[l];
cannot be done, if you do it like this l must have a constant value.
A = B;
will perform a shallow copy instead of a deep copy.
You can see the diffrence here: What is the difference between a deep copy and a shallow copy?
cout<<C[0]<<C[1];
will print the numbers joined together without parsing.
As to how to fix this code one implementation you might be aiming towards can be:
#include <iostream>
using namespace std;
int largest(int* A, int l)
{
int big=-1;
int i;
int index=0;
for(i=0;i<l;i++)
{
if(A[i]>big)
{
big=A[i];
index=i;
}
}
return index;
}
void sort(int* A,int l)
{
int j;
int *B=new int[l];
for(int i=0;i<l;i++)
{
j = largest(A,l);
B[l-i-1] = A[j];
A[j] = -1;
}
for(int i=0;i<l;i++)
{
A[i]=B[i];
}
}
int main()
{
int C[3] = {2,5,1};
sort(C,3);
cout<<C[0]<<" "<<C[1];
return 1;
}

Vector (push_back); g++ -O2; Segmentation fault

I'm having problem with vector, (in the usage of push_back) but it only appears when using additional g++ flag -O2 (I need it).
#include <cstdio>
#include <vector>
typedef std::vector<int> node;
typedef std::vector<node> graph;
int main()
{
int n, k, a, b, sum;
bool c;
graph g(n, node());
c = scanf("%i%i", &n, &k);
for(int i=0; i<n; i++)
{
sum=2;
for(int j=0; j<i; j++)
sum*=2;
for(int j=0; j<sum; j++)
{
if(j%2==0)
c = scanf("%i", &a);
else
{
c = scanf("%i", &b);
a += b;
g[i].push_back(a); //---------------LINE WHICH CAUSES SEGMENTATION FAULT
}
}
}
for(int i=n-2; i>=0; i--)
{
for(size_t j=0; j<g[i].size(); j++)
{
if(g[i+1][(j*2)] >= g[i+1][(j*2)+1])
g[i][j] = g[i+1][j*2];
else
g[i][j] = g[i+1][(j*2)+1];
}
}
printf("%i\n", g[0][0]);
return 0;
}
I think you have:
graph g(n, node());
c = scanf("%i%i", &n, &k);
in the reverse order. As it stands, the variable 'n' which you use to size graph is not initialised.
Initializing the vector with n before the input operation means you're invoking the dreaded Undefined Behavior. As stated here, the program is allowed to do anything after that.
Works perfectly if you initialize n as I already mentioned in my comment. Change the first lines to:
int n, k, a, b, sum;
int c;
c = scanf("%i%i", &n, &k); // initialize n *first*
if(c != 2) return -1; // scanf does not return bool but the number of parsed arguments
graph g(n, node());