I'm trying to make a dynamic matrix that is based on an integer pointer to pointer, this variable is allocated dynamically, but I'm having a little trouble using it, I don't know if I am using it wrong or something, but the outcome is not as expected. Is it something wrong that I'm doing or am I not thinking this through?
void pkn(int n, int k)
{
int chec = checagemInicial(n,k);
if(chec == 1)
{
return;
}
int mat[n];
int **resultado = NULL, **newMem;
int posicoes = 0;
initiateArray(mat, n);//initialize the matrix with one's
while(functionthatchecksthings1(mat, n, k) == 0)//this 2 function works no need to worry
{
if(functionthatchecksthings2(mat, n , k))
{//i think the problem might be or here
newMem = realloc(resultado, ((sizeof(int)*n)+(posicoes*sizeof(int)*n)));
if(newMem)
{//or here
resultado = newMem;
}
int i = 0;
for(i; i<n;i++)
{//or here but don't know where
resultado[posicoes][i] = mat[i];
}
posicoes++;
}
somaArray(mat, k, n-1);
}
//or in the very least case i'm printing it wrong
printaArray(resultado, n, posicoes);
system("pause");
free_matrix(posicoes, resultado);
}
This one is the function that prints the pointer, it might be wrong here too, but I seriously don't know.
void printaArray(int **ar, int n, int p)
{
int i = 0, j;
for(i; i < p; i++)
{
j = 0;
for(j; j < n; j++)
{
printf("%d ",(ar[i][j]));
}
printf("\n");
}
printf("%d\n", p);
}
I would like to thank everyone and I'm sorry if I haven't made myself clear, or if I've said something wrong/misspelled anything
Related
I've been trying to return an array in C. I'm mostly acquainted with Java (where it's comparatively easier to return an array).
This is what I'm trying to do right now:
#include <stdio.h>
#include <stdlib.h>
int * duplicates(int[],int);
int main() {
int arr[] = {3,5,6,5,9,5,10,11,3};
int n = sizeof(arr)/sizeof(arr[0]);
int * tempArray = duplicates(arr,n);
for (int i = 0; i < n; i++) {
printf("%d \t",tempArray[i]);
}
}
int * duplicates(int arr[], int n) {
int tempArray[n];
int r = 0;
int flag = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
if (arr[i] == arr[j]) {
for(int k = 0; k < r; k++) {
if(arr[i] == tempArray[k]) {
flag = 1;
}
}
if (flag == 0) {
tempArray[r++] = arr[i];
flag = 0;
} else {
break;
}
}
}
}
return tempArray;
}
And this, to no surprise - crashes my program. How I can return an array in C, because that feels like a bare-minimum, something I should know before I can move further into the language.
Yeah, just allocate the memory like here Returning an array using C
int * duplicates(int arr[], int n) {
int *tempArray;
...
tempArray = (int *)malloc(sizeof(int) * n);
if (tempArray == NULL)
return (NULL);
...
This will work. Google why you should 'dynamically allocate the memory' and 'pointer'.
the array you created inside function duplicate has automatic storage duration since it's on the stack of function unlike in java in which arrays are objects and allocated on the heap. anyway I just wanted to add some NOTE which is don't use VLA(variable length arrays) like int array[n] instead use literals like int array[50] since VLA generate a lot of assembly code(affect performance a tiny bit) and can have security problems like stack overflows or cause the program to crash. Also, not all compilers implement it(portability issues).
I want to a function named sortPointers() that sets an array of integer pointers to point to the elements of another array in ascending order.
What I have done so far is
void sortP(int src[], int *ptrs[], int n)
{
int temp;
for(int i = 0; i< n ; i++)
{
ptrs[i] = & src[i]; // assign the address of each number in the src[] to the array of pointers
}
while (1)
{
int flag = 0;
for(int i = 0; i< n;i++)
{
if ( *(ptrs[i]) > *(ptrs[i+1])) //bubble sort
{
temp = *(ptrs[i]);
*(ptrs[i]) = *(ptrs[i+1]);
*(ptrs[i+1]) = temp;
flag = 1;
}
}
if(flag == 0);
break;
}
for(int i = 0; i< n;i++)
{
printf("%i\n",ptrs[i]);
}
}
In main function , I call this function
main()
{
int a[5] = {5,4,3,2,1};
int *ptrs[5]= {&a[0],&a[1],&a[2],&a[3],&a[4]};
sortP(a, *ptrs, 5);
}
My result are addresses, If I want to print out the actual value that the pointers point to (1,2,3,4,5) ,what should I change in the printf()?
THanks
P.S. I try *ptrs[i] before , but I got strange number though , not the ones in src[]..
My result are addresses
Technically, your results are undefined behavior, because %i expects an int, not an int*.
Fixing this problem is simple: add a dereference operator in front of ptrs[i], like this:
for(int i = 0; i< n;i++) {
printf("%i\n", *ptrs[i]);
}
I got strange number though , not the ones in src[]
The real problem with your code is that you are swapping pointers incorrectly. In fact, you can tell that it's incorrect simply by looking at temp: it needs to be int*, not int and the dereferences on the swap need to go away.
see annotations :
void sortP(int src[], int *ptrs[], int n)
{
int temp;
for(int i = 0; i< n ; i++)
{
ptrs[i] = & src[i]; // assign the address of each number in the src[] to the array of pointers
}
while (1)
{
int flag = 0;
// check if i < n-1, not n
for(int i = 0; i< n-1;i++)
{
if ( *(ptrs[i]) > *(ptrs[i+1])) //bubble sort
{
temp = *(ptrs[i]);
*(ptrs[i]) = *(ptrs[i+1]);
*(ptrs[i+1]) = temp;
flag = 1;
}
}
if(flag == 0)
break;
}
for(int i = 0; i< n;i++)
{
//*ptrs[i] instead of ptrs[i]
printf("%i ",*ptrs[i]);
}
}
int main(void)
{
int a[5] = {5,4,3,2,1};
int *ptrs[5];//= {&a[0],&a[1],&a[2],&a[3],&a[4]};
sortP(a, ptrs, 5);
}
#include<stdio.h>
#include<stdlib.h>
int** createMatrix(int n)
{
int i, a, **tab,x;
tab=(int**)malloc(n*sizeof(int*));
if(tab==0)
{
return NULL;
free(tab);
}
for(i=0;i<n;i++)
{
tab[i]=(int*)malloc(n*sizeof(int));
if(tab[i]==NULL)
{
for(x=0;x<i;x++)
{
free(tab[x]);
}
free(tab[i]);
return NULL;
}
}
}
void fillMatrix(int*** tab, int n)
{
int i, a;
for(i=0;i<n;i++)
{
for(a=0;a<n;a++)
{
*tab[i][a]=(a*i);
}
}
}
int main()
{
int roz, **tab,i,x;
printf("size of the array: \n");
scanf("%d",&roz);
tab=createMatrix(roz);
if(tab==NULL)
{
printf("error");
return -1;
}
fillMatrix(&tab, roz);
for(i=0;i<roz;i++)
{
printf("\n");
for(x=0;x<roz;x++)
printf("%d",tab[i][x]);
}
return 0;
}
Hi! I need to write a program that makes 2d arrays and I want to fill them with multiplication table. Program compiles without single warning or error, but after puttintan input it crashes. And by the way, could you tell me why I have to put 3x* in fillMatrix?
int** createMatrix(int n)
You should be returning the double pointer from the function which I see you are not doing.
int** createMatrix(int n)
{
int i, a, **tab,x;
tab=(int**)malloc(n*sizeof(int*));
// Do your allocations and other stuff
return tab;
}
Take care of accessing the elements using triple pointer. Like
(*tab)[i][a] = (a*i);
You can get the job done using doule pointers itself.
You have several problems
Pointeless free(tab) in your createMatrix() function, it's after the return statement, it will never be executed.
You free the tab[i] element which is NULL in createMatrix() inside the loop where you malloc the pointers of the array.
What you should do is
free(tab);
instead.
You never return the malloced tab.
Your fillMatrix() function is unecessarily taking a int *** triple pointer, you don't need that, if you pass the pointer you directly modify the data.
You have an operator precedence issue in fillMatrix()
*tab[i][a] = (a*i);
this doesn't mean what you think, first [] is applied, and then you dereference it with * which is equivalent to
*(tab[i][a]) = (a * i); -> *(tab[i][a]) -> tab[i][a][0]
what you want is
(*tab)[i][a] = a * i;
You don't free the pointers after printing them.
This is your code with all this issues fixed.
#include <stdio.h>
#include <stdlib.h>
int **createMatrix(int n)
{
int i, **tab, x;
tab = malloc(n*sizeof(int*));
if (tab == 0)
return NULL;
for (i = 0 ; i < n ; i++)
{
tab[i] = malloc(n * sizeof(int));
if (tab[i] == NULL)
{
for (x = 0 ; x < i ; x++)
free(tab[x]);
free(tab);
return NULL;
}
}
return tab;
}
void fillMatrix(int **tab, int n)
{
int i, a;
for (i = 0 ; i < n ; i++)
{
for (a = 0 ; a < n ; a++)
{
tab[i][a] = (a*i);
}
}
}
int main()
{
int roz, **tab, i, x;
printf("size of the array: \n");
scanf("%d", &roz);
tab = createMatrix(roz);
if (tab == NULL)
{
printf("error");
return -1;
}
fillMatrix(tab, roz);
for (i = 0 ; i < roz ; i++)
{
printf("\n");
for (x = 0 ; x < roz ; x++)
printf("%4d ", tab[i][x]);
printf("\n");
free(tab[i]);
}
free(tab);
return 0;
}
And by the way, could you tell me why I have to put *** in fillMatrix?
That is an excellent question. Incidentally, it provides the key to answering the "why does my program crash" question. The reason the program crashes is that you are using the matrix incorrectly: you treat it like a 2D array of pointers, rather than a pointer to a 2D array. If you add parentheses, your program would stop crashing:
(*tab)[i][a]=(a*i);
Better yet, change the program to take ** that it needs:
void fillMatrix(int** tab, int n) {
...
tab[i][a]=(a*i); // <<== No asterisk
}
...
fillMatrix(tab, roz); // <<== No ampersand
Note: when you compile your program, you should see the "control reaches the end of non-void function without returning a value". This is because you forgot to add return tab at the end of the function that creates your matrix.
Demo.
You asked:
And by the way, could you tell me why I have to put 3x* in fillMatrix?
That is not necessary. You could use:
void fillMatrix(int** tab, int n)
{
int i, a;
for(i=0;i<n;i++)
{
for(a=0;a<n;a++)
{
tab[i][a]=(a*i);
}
}
}
I am working on a class project to solve the wandering Salesman problem, which is basically the TSP, except you don't return to the source. I took the approach of finding all possible permutations of a set of vertices and then iteratively calculating the length and comparing them to find the smallest. I know it's not the best approach, but its what our professor wanted.
When I run the code below, it works fine and gives me the right answers when the input array is less than 7 X 7. But when its 7 X 7, it returns "Bus Error: 10", and if the size is 12 x 12, it returns "Segmentation Fault : 11". I looked up these problems for hours and couldn't figure out what's wrong. I'm not much of an expert in C programming, and I'm honestly really confused with pointers. Thank you so much for the help, I appreciate it greatly!
Oh, and sorry about the messy code.
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include<stdlib.h>
int x = 0;
int a[];
void swap (int v[], int i, int j) {
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
/* recursive function to generate permutations */
int* perm (int v[], int n, int i) {
/* this function generates the permutations of the array
* from element i to element n-1
*/
int j;
/* if we are at the end of the array, we have one permutation
* we can use (here we print it; you could as easily hand the
* array off to some other function that uses it for something
*/
if (i == n) {
for (j=0; j<n; j++){ a[x] = v[j]; x++;} // printf ("%d ", v[j]);
// printf ("\n");
}
else
/* recursively explore the permutations starting
* at index i going through index n-1
*/
for (j=i; j<n; j++) {
/* try the array with i and j switched */
swap (v, i, j);
perm (v, n, i+1);
/* swap them back the way they were */
swap (v, i, j);
}
return a;
}
int fact(int n){
if(n==1){
return 1;
}
else{
return n * fact(n-1);
}
}
int findShortestPath(int **v , int length){
int pathArrayMultiplier = 0;
int ShortestPathLength = 99999;
printf("Called");
int arrayOfVertices[length-1];
for(int i=0 ; i<length-1 ; i++){
arrayOfVertices[i] = i+2;
}
int n = fact(length-1);
bool doBreak = false;
int pathArray[length-1];
//printf(" Called 3");
printf(" %d" , n);
int* Answer;
Answer = malloc(sizeof(int *));
Answer = perm(arrayOfVertices , length-1 , 0);
printf("Called 4");
int j =-1;
for(int i=0 ; i< n*(length-1) ; i++){
doBreak = false;
j++;
printf("%d " , *(Answer + i));
pathArray[j] = *(Answer+i);
if(j == length-2)
{
j = -1;
// Check for negative values. If any value is negative, disregard path
int checklength = *((int *)v + 0 *length + (pathArray[0]-1));
if(checklength < 0){
printf("First check called");
continue;}
for(int i =0 ; i<length-2 ; i++){
if(*((int *)v + (pathArray[i]-1) * length + (pathArray[1 + i]-1)) < 0){
doBreak = true;
printf("Second Check called");
break;}
}
if(doBreak) { pathArrayMultiplier++; continue;}
printf("\n");
int pathLength = *((int *)v + 0 *length + (pathArray[0]-1));
for(int i =0 ; i<length-2 ; i++){
pathLength = pathLength + *((int *)v + (pathArray[i]-1) * length + (pathArray[1 + i]-1));}
printf("Path Length is %d\n" , pathLength);
if(pathLength < ShortestPathLength) { ShortestPathLength = pathLength;}
}
}
printf("\n\n Shortest Path Length is %d \n" , ShortestPathLength);
return ShortestPathLength;
}
int main () {
int len = 5;
printf("Array is initialized");
int v[7][7] = {0,7,-1,10,1,-1,-1,7,0,-1,-1,10 ,-1 ,1,-1,-1,0,10,1,10,-1,10,-1,10, 0,8,-1,-1,-1,10,1,8,0,10,-1,-1,-1,10,-1,10,0,70,-1,1,-1,-1,-1, 70 , 0};
printf("Array is initialized");
int **realArrayPointer = v;
findShortestPath(realArrayPointer, 7);
return 0;
}
Your code is a mess and practically unreadable. However, I took it upon myself as a challenge to see if I could spot your bug. What I saw is that you declare an empty array at the top:
int a[];
and then you write to this array:
a[x] = v[j];
x++;
You never even reset x back to 0, anywhere. So basically, right from the start you are writing to unallocated memory, but the bigger your input set, the more unallocated memory you write to.
There could be other problems with your code. I definitely saw a whole bunch of other things that indicated an incorrect understanding of pointers, but they wouldn't necessarily cause a fatal error. Please at the very least get some kind of auto-indent program to make your code readable.
Here is a segment of my (incomplete) code
int rows(int board[][9]){
int badUnits = 0, i = 0, n = 9, j, z = 0;
int (*temp)[9];
//Sort each row of 2d array
for (z; z < n; z++){
for (i; i < n; i++){
for (j = i; j < n; j++){
if (board[z][i] > board[z][j]){
temp = board[z][i];
board[z][i] = board[z][j];
board[z][j] = temp;
}
}
}
}
printf ("%d\n", temp[1][0]);
printf ("%d\n", temp[1][1]);
return badUnits;
}
The function takes a 9*9 array.
I get a segmentation fault when the print statements are executed.
I believe my sort code is correct because it is similar to what I use for 1d arrays and I think everything else is correctly assigned.
So the culprit would be my temp variable. I have gone through and tried to assign values to it, tried to change the type, and have taken into account that the 2d array decays into a pointer but is not actually a pointer.
The conclusion I am left with is that this is a dynamic allocation issue. Can someone please lend a hand and assist me in fixing this? I have exhausted my knowledge base and am stuck.
To clarify: I decided to print the temp variable because I thought it would lend some information. The main problem was that the swap was not working, and I was still left with an unsorted array when I originally attempted to print out the board[][]. I know that board is what I am SUPPOSED to be printing.
Thank you for any help!
You assign an int value to temp
temp = board[z][i]; // Temp now is a what ever value was at
// That location in the array e.g. 42
You then treat temp as if it was the address in memory of an integer array
temp[1][1] // treat temp as a pointer and find the integer
// 10 integers further along then temp.
Also sometime temp will not have been initialised (never assigned to) in this case your going to get unexpected behaviour depending on what the last value stored where temp is now (Lets call it a random number).
Did you mean to output the values in board?
printf ("%d\n", board[1][0]);
printf ("%d\n", board[1][1]);
One thing to notice is that the variable temp will only get assigned to if a swap occurs, if the sorting algorithm was correct that is still a situation that could occur with a input corresponding to a sorted board.
But more importantly, the variable temp is used as an int during the swap. Later that integer value is interpreted as a pointer in the expressions temp[1][0] and temp[1][1], which in all likelihoods is not a valid address. You may want to change temp to be declared as:
int temp;
And figure out exactly what you would like to print. If it is whatever one of the two swapped values was (for the last swapped pair in the loop), then you would print it as:
printf("%d", temp);
Else, you would have to add logic according to what you really want to do.
Note that a single pass of this algorithm would not perform a complete sort, but I guess that's one of the reason why you said the provided code was not complete.
Something like this?
#include <stdio.h>
#include <stdlib.h>
void printArray(int** arr, int w, int h) {
for (int i = 0; i < w; ++i) {
for (int j = 0; j < h; ++j) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void sortArray(int** arr, int w, int h) {
for (int row = 0; row < h; ++row) {
for (int col = 0; col < w; ++col) {
for (int i = 0; i < w; ++i) {
if (arr[row][i] > arr[row][col]) {
int tmp = arr[row][col];
arr[row][col] = arr[row][i];
arr[row][i] = tmp;
}
}
}
}
}
int main() {
int w = 9, h = 9;
int** arr = (int**)malloc(sizeof(int*) * w);
for (int i = 0; i < w; ++i) {
arr[i] = (int*)malloc(sizeof(int) * h);
for (int j = 0; j < h; ++j) {
arr[i][j] = rand() % 10;
}
}
printf("Unsorted:\n");
printArray(arr, w, h);
sortArray(arr, w, h);
printf("Sorted:\n");
printArray(arr, w, h);
for (int j = 0; j < h; ++j) {
free(arr[j]);
}
free(arr);
return 0;
}