void inputArray(int* *pa, int *n)
{
do {
printf("Input the elements: ");
scanf_s("%d", n);
if (*n < 0)
{
printf("Error! Input again\n");
}
} while (*n < 0);
*pa = (int*)malloc(*n * sizeof(int));
for (int i = 0; i < *n; i++)
{
printf("Elements a[%d]: ", i);
scanf_s("%d", pa + i);
}
}
void outputArray(int* *pa, int n)
{
printf("\nContent of the array\n");
for (int i = 0; i < n; i++)
{
printf("a[%d] = %d\n", i, *(pa + i));
}
}
int main()
{
int *A;
int n;
inputArray(&A, &n);
outputArray(&A, n);
free(A);
_getch();
return 0;
}
When the program display the array, I got the error "Exception thrown at 0x00AD372D (ucrtbased.dll)"
I'd tried many times to fix the error, but it still displays the error when the program displays the output of array, please give me some advice. Thanks for reading.
A debugger will have shown you where the problems are.
You pass the address of a pointer to inputArray and get it as an int **: fine
You allocate the array with *pa = (int*)malloc(*n * sizeof(int)); : almost fine. All indirections levels are correct, but you should not cast malloc in C (should be: *pa = malloc(*n * sizeof(int));)
But scanf_s("%d", pa + i); is plain wrong. pa is a pointer that contains the address of the allocated array, so the array is at *pa not at pa. You should write scanf_s("%d", *pa + i);
For outputArray, you have no reason to pass a pointer to the array. But if you do, the values will be at (*pa)[i], not at *(pa + i) which is the same as pa[i], so you should use : printf("a[%d] = %d\n", i, (*pa)[i]);.
But the correct way would be:
void outputArray(int *pa, int n)
{
printf("\nContent of the array\n");
for (int i = 0; i < n; i++)
{
printf("a[%d] = %d\n", i, pa[i]);
}
}
...
outputArray(A, n);
You have a double pointer int* *pa in you function inputArray, of wich you allocated space for *pa. and you are reading value to pa. First you should allocate memory for pa then read value to it.
for (int i = 0; i < *n; i++)
{
pa[i] = malloc(sizeof(int));
printf("Elements a[%d]: ", i);
scanf_s("%d", pa[i]);
}
Related
This is my first time quesiton, so my explanation could be bad.....
I want to allocate memory for arr1 and arr2 to store and output four numbers each. There is no problem with compiling, but if you run the code, the program automatically with put the third number in the memory arr1.
#include <stdio.h>
#include <stdlib.h>
void ARR1_INPUT(int **arr1, int size)
{
*arr1 = (int *)malloc(sizeof(int) * size);
if (arr1 != NULL)
{
for (int i = 0; i < size; i++)
{
printf("put your number of %d index -> ", i + 1);
scanf("%d", arr1[i]);
}
}
else printf("Memory allocation fail");
}
void ARR2_INPUT(int **arr2, int size){
*arr2 = (int *)malloc(sizeof(int) * size);
if (arr2 != NULL)
{
for (int i = 0; i < size; i++)
{
printf("put your number of %d index -> ", i + 1);
scanf("%d", arr2[i]);
}
}
else printf("Memory allocation fail"):
}
int main(void){
int size;
int *arr1;
int *arr2;
printf("how many number are you gonna put in each memory -> "); scanf("%d", &size);
ARR1_INPUT(&arr1, size);
ARR2_INPUT(&arr2, size);
printf("%d, %d, %d, %d", arr1[0], arr1[1], arr1[2], arr1[3]);
printf("%d, %d, %d, %d", arr2[0], arr2[1], arr2[2], arr2[3]);
free(arr1);
free(arr2)
}
Thank you so much for your help!
There were some errors in the code. I'll just post the second function with comments. Mostly, it's because of wrong level of indirection.
void ARR2_INPUT(int **arr2, int size){
*arr2 = malloc(sizeof(int) * size); // cast is undesirable
if (*arr2 != NULL) // was incorrect level of indirection
{
for (int i = 0; i < size; i++)
{
printf("put your number of %d index -> ", i + 1);
scanf("%d", &(*arr2)[i]); // was incorrect level of indirection
}
}
else printf("Memory allocation fail"); //: was syntax error
}
Also as commented, the code reports exactly 4 array elements: this should be done in loops controlled by size.
There are other improvements that can be made, such as checking the return value from the scanf calls, and better follow-through from failed memory allocation.
I'm coding a game "Tic Tac Toe"
and I ask each player to enter their next move in two different functions,
then I save their moves in 2D array, and save this array in another 2d array in the main function.
but when I print the array it changes the char symbol when the second player enters his next move.
PS: it's a char array.
here is my code
char player1(char board[N][N], int n)
{
int k, l;
print_player_turn(1);
scanf("%d%d", &k, &l);
board[k - 1][l - 1] = 'X';
print_board(board, n);
return board;
}
char player2(char board[N][N], int n)
{
int k, l;
print_player_turn(2);
scanf("%d%d", &k, &l);
board[k - 1][l - 1] = 'O';
print_board(board, n);
return board;
}
int main()
{
char board[N][N];
int n;
print_welcome();
print_enter_board_size();
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
board[i][j] = '_';
print_board(board, n);
char* ptr = board;
while (isFull(board,n)==0)
{
board[0][0] = player1(board, n);
if (XloseGeneral(board, n) == 1)
{
print_winner(2);
return 0;
}
board[0][0] = player2(board, n);
if (OloseGeneral(board, n) == 1)
{
print_winner(1);
return 0;
}
}
print_tie();
}
I would suggest you expand the scope of the 2D array 'board' such that it is accessible to all methods including player 1 and player 2, instead of passing it as a parameter.
This way you can make sure that the modification is being done on the same variable, and that no reinitialisation happens, which results in loss of the previous entry.
Arrays are passed to functions by reference. Which means, a pointer to the array is passed to the function. Hence, any modifications done to the array inside the function will reflect the caller (the main method in your case). So, make your function void as it doesn't need to return anything, and remove the return statement from it.
As others have said you don't need to return the board, you can just pass the pointer to the board. Here's a short example based on your code:
#include <stdio.h>
#include <stdlib.h>
void player1(char **board);
void player2(char **board);
void print_board(char **board, int n);
void player1(char **board){
int k, l;
fprintf(stderr, "Player 1, enter grid position:\n");
scanf("%d%d", &k, &l);
board[k - 1][l - 1] = 'X';
}
void player2(char **board){
int k, l;
fprintf(stderr, "Player 2, enter grid position:\n");
scanf("%d%d", &k, &l);
board[k - 1][l - 1] = 'O';
}
void print_board(char **board, int n){
for (int i = 0; i < n; i++){
for( int j = 0; j < n; j++ ){
fprintf(stdout, "%c ", board[i][j]);
}
fprintf(stdout, "\n");
}
}
int main()
{
int n;
char **board;
fprintf(stdout, "Type in the board size:\n");
scanf("%d", &n);
// allocate memory for the board
board = (char **) malloc(n * sizeof(char*));
for (int i = 0; i < n; i++){
board[i] = (char *)malloc(n * sizeof(char));
for (int j = 0; j < n; j++){
board[i][j] = '_';
}
}
print_board(board, n);
player1(board);
player2(board);
print_board(board, n);
return 0;
}
In the code below, i am taking n as a user input, and depending on its value i have allocated memory to the pointer array (both n and pointer array are a part of a structure). The whole code works well for values of n below 4, anything 4 or beyond, its giving a segmentation fault while inputting values in the pointer array.
I can imagine that it might be because the memory isn't getting allocated but why its only beyond 4 I don't understand
Here is a snippet where the problem is happening.
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
// static int n;
typedef struct test_case {
int n;
int *test[];
} testCase;
int maxsc(testCase *test_case_ptr);
int find_maximum(int *ptr, int n);
int main() {
int T;
int x = 0;
int temp;
testCase *test_case_ptr;
printf("T = ");
scanf("%d", &T);
printf("\n");
for (int i = 0; i < T; i++) {
printf("N = ");
scanf("%d", &test_case_ptr->n);
temp = test_case_ptr->n;
printf("\n");
test_case_ptr = (testCase *)malloc(sizeof(struct test_case));
for (int i = 0; i < temp; i++) {
test_case_ptr->test[i] = malloc(sizeof(int *) * test_case_ptr->n);
}
test_case_ptr->n = temp;
// printf("%d\n", test_case_ptr->n);
printf("give values\n");
for (int j = 0; j < test_case_ptr->n; j++) {
for (int k = 0; k < test_case_ptr->n; k++) {
scanf("%d", &test_case_ptr->test[j][k]);
}
}
int max_score = maxsc(test_case_ptr);
printf("\n");
printf("The max_score_%d = %d \n", x++, max_score);
}
}
First, you try to use the test_case_ptr struct before allocating mem for it. Second, when using a flexible array, you need to alloc the mem for it when you malloc the mem for the struct.
scanf("%d", &temp);
// Allocate mem for the struct plus the array
test_case_ptr = malloc(sizeof(struct test_case) + sizeof(int *) * temp);
test_case_ptr->n = temp;
// Allocate each row in the array
for (int i = 0; i < test_case_ptr->n; i++) {
test_case_ptr->test[i] = malloc(sizeof(int) * test_case_ptr->n);
}
// .....
For an assignment I need to make a sorting algorithm for n amount of vector arrays. The assignment specifically tells me to not swap the value of what the pointers are pointing to, but the address that is stored in those pointers. The result will then be printed using those pointers.
My problem is that I can't seem to accomplish the swapping of the addresses that the pointers contain. I have searched SO for related questions but they almost all change the values of where the pointers are referring to.
So far I have this:
Swap function
void swap(double **p, double **q, int i, int j){
double* tmp;
tmp = &p;
*p= &q;
*q = tmp;
printf("\tSwapped [%d][%d] and [%d][%d]\n", i,j, (i-1), j);}
And my main function
int main (void){
int dim, num, *tmp;
int i, j, a;
double **w;
scanf("%d %d", &dim, &num); /* read the dimension and amount of array*/
w = calloc(num, sizeof(double *)); /* allocate array of num pointers */
for (i = 0; i<num; i++)
{
/*allocate space for a dim-dimensional vector */
w[i] = calloc(dim, sizeof(double));
/* read the vector */
for (j = 0; j < dim; j++)
{
scanf("%le", &w[i][j]);
}
}
a = 0;
while (a <= num)
{
/*sort num times*/
i = (num -1);
while(i != 0)
{
if ((argument1) > (argument2) )
{ /*swap each columns of the rows individually*/
printf("\tSwapping..\n");
for(j = 0; j<dim; j++)
{
swap(&w[i][j], &w[i-1][j], i, j);
}
}
i--;
}
a++;
}
for(i=0; i<num; i++)
{
for(j=0; j<dim; j++)
{
printf("%e ",w[i][j]);
}
printf("\n");
}
return 0;
}
When i test this program, it does enter the swap function correctly but the printed result is the same as the input (so not swapped). Can anyone help me why this isn't working?
The swap function can look like
void swap( double **p, double **q )
{
double *tmp = *p;
*p = *q;
*q = tmp;
}
As for the code that is used to sort arrays then it is invalid and does not make sense. At least the variables argument1 and argument2 are not declared.
void load(int *n, int *x, int **arr)
{
arr = (int**)malloc(sizeof(int*)*(*n));
for(int i = *n; i >= 0; i--)
{
scanf("%d", &arr[i]);
}
}
int main()
{
int n = 0, x = 0;
int *arr;
load(&n, &x, &arr);
printf("%d", arr[1]);
return EXIT_SUCCESS;
}
The program compiles properly, but it throws windows error during the printf() in main function. Displaying just "arr" gives random big numbers. What is wrong here?
arr = (int**)malloc(sizeof(int*)*(*n));
doesn't change anything in main, it only overwrites the copy of the pointer (address of arr in main) that load receives.
What the function should do is change arr in main, for that, you have to dereference the argument,
*arr = (int*)malloc(sizeof(int)*(*n)); // cast for C++ compiler left in
to change the value of arr in main. (The object that the argument arr of load points to, that is arr in main, needs to be changed, hence you need to modify *arr in load.)
The scans should then be
scanf("%d", &(*arr)[i]);
or (equivalent)
scanf("%d", *arr + i);
#include <stdio.h>
#include <stdlib.h>
void load(int *n, int *x, int **arr)
{
int i = 0;
*arr = (int*) malloc(*n * sizeof(int));
if(!*arr) {
perror("Can not allocate memory!");
return;
}
for(i = *n; i >= 0; i--)
{
scanf("%d", *arr + i);
}
return;
}
int main()
{
int n = 0, x = 0;
int *arr;
int i;
/* You probably need to initialize n */
n = 5;
load(&n, &x, &arr);
for(i = n; i >= 0; i--)
{
printf("%d - %d\n", i, arr[i]);
}
return EXIT_SUCCESS;
}