I am trying to develop the TicTacToe game in C and I am using the following structures.The myboard->a member is used to store 'X' or 'O' ,meaning the move a player has made in the same coordinates as the board , ie. 'X' in (1.1) or 'O' (3.1)
typedef struct{
int** a;
int size;
}_board;
typedef _board* board;
board myboard =(board) malloc(sizeof(board));
scanf_s("%d", &(myboard->size));
Size=is the size of the TicTacToe board nxn.
myboard->a =(int**)malloc(myboard->size*sizeof(char *));
if (myboard->a = NULL)
{
printf("ERROR!!!");
}
Until this point everything seems to work but when a try to allocate memory as you see bellow, a get a segmentation fault.
int i;
for (i = 0; j<myboard->size; i++)
{
myboard->a[i] = malloc(sizeof(char));
if (myboard->a[i] == NULL)
{
printf("ERROR");
}
}
I am using free for its malloc at the end of me program.
Thanks, in advance for any answer , and sorry for my bad english. Any help is apreciated.
I don't really understand why you are using a int** variable for storing your board data, when you could just use one simple int*, which you could later assign with malloc(3) as in:
int* b_data;
int b_size = 9;
b_data = malloc(b_size * sizeof(int));
// ... Your code
free(b_data);
If however, you really want to use a int** variable, you could do something like:
int** b_data;
int b_size_x = 3;
int b_size_y = 3;
int i;
b_data = malloc(b_size_x * sizeof(int*));
for(i = 0; i < b_size_x; i++)
*(b_data + i) = malloc(b_size_y * sizeof(int));
// ... Your code where you access your array of size_x containing
// arrays of size_y of int typed "cells"
for(i = 0; i < b_size_x; i++)
free(*(b_data + i));
free(b_data);
But this is really unnecessarily complicated, and I would dis-advise from doing so unless for learning purposes: in most cases, the allocated memory will be contiguous, so the second solution will allocate a nearly identical structure in memory, but will be less efficient (the "2D" array solution takes b_size_x times sizeof(int*) more memory), and the first solution will be simpler to read/write (so less prone to bugs, and easier to maintain).
Concerning your code, your problem is that myboard->a is NULL right after the "check" (which is in fact an allocation - note that the "ERROR" is never shown because myboard-> is then NULL, which evaluate to 'false'.):
if (myboard->a = NULL)
which should be:
if (myboard->a == NULL)
In addition, as pointed by #WhozCraig in his comment on your post, you might want to use i in the condition of your for loop, rather than j; and you also probably want to use int and int* types rather than char and char* types respectively in your malloc(s), since the a member of the board structure is an int**. Oh and also, think about putting newlines after your printf(3) strings, or use puts(3).
Related
I am relatively new to C and have coded (or more precise: copied from here and adapted) the functions below. The first one takes a numpy array and converts it to a C int array:
int **pymatrix_to_CarrayptrsInt(PyArrayObject *arrayin) {
int **result, *array, *tmpResult;
int i, n, m, j;
n = arrayin->dimensions[0];
m = arrayin->dimensions[1];
result = ptrvectorInt(n, m);
array = (int *) arrayin->data; /* pointer to arrayin data as int */
for (i = 0; i < n; i++) {
result[i] = &array[i * m];
}
return result;
}
The second one is used within the first one to allocate the necessary memory of the row vectors:
int **ptrvectorInt(long dim1, long dim2) {
int **result, i;
result = malloc(dim1 * sizeof(int*));
for (i = 0; i < dim1; i++) {
if (!(result[i] = malloc(dim2 * sizeof(int)))){
printf("In **ptrvectorInt. Allocation of memory for int array failed.");
exit(0);
}
}
return result;
}
Up to this point everything works quite fine. Now I want to free the memory occupied by the C array. I have found multiple threads about how to do it, e.g. Allocate and free 2D array in C using void, C: Correctly freeing memory of a multi-dimensional array, or how to free c 2d array. Inspired by the respective answers I wrote my freeing function:
void free_CarrayptrsInt(int **ptr, int i) {
for (i -= 1; i >= 0; i--) {
free(ptr[i]);
}
free(ptr);
}
Nontheless, I found out that already the first call of free fails - no matter whether I let the for loop go down or up.
I looked for explenations for failing free commands: Can a call to free() in C ever fail? and free up on malloc fails. This suggests, that there may have been a problem already at the memory allocation. However, my program works completely as expected - except memory freeing. Printing the regarded array shows that everything should be fine. What could be the issue? And even more important: How can I properly free the array?
I work on a Win8 64 bit machine with Visual Studio 10 64bit compiler. I use C together with python 3.4 64bit.
Thanks for all help!
pymatrix_to_CarrayptrsInt() calls ptrvectorInt() and this allocation is made
if (!(result[i] = malloc(dim2 * sizeof(int)))){
then pymatrix_to_CarrayptrsInt() writes over that allocation with this assignment
result[i] = &array[i * m];
causing a memory leak. If array is free()'d then attempting to free() result will fail
OK, so the problem is basically like the title. Couldn't find a question that got all bits of it, so I figured I'd ask.
Say I want an array of structs shaped like the following
typedef struct s_woo{
char** n;
char* x;
} t_woo;
So I believe I should do
t_woo* woos = malloc(num_woos * sizeof(*woos));
Seems simple enough (and should deter people from yelling at me for my habit of casting malloc).
Then I want to initialize the things in each of those structs.
So intuitively I do:
for(i = 0; i < num_woos; i++){
num_ns = randomint1 / randomint2; //let's say num_ns is big, like 250-ish, average, and changes every round of the loop
woos[i].n = malloc(num_ns * sizeof(char*));
woos[i].x = malloc(num_ns * sizeof(char));
for(j = 0; j < num_ns; j++){
woos[i].n[j] = malloc(16 * sizeof(char)); // I just want 16 characters per char*
}
}
This is the boiled down version of what I have in my code. I want to know what can possibly go wrong with what I've written - like any possible thing. I'm not looking for anything in particular, just general problems with the above, like memory/heap issues, pointer mistakes etc.
Leave out "Virtual Memory Exhausted". My code error checks for that using a wrapper function on malloc, so I'm very sure that's not it.
Even better:
static const size_t woo_n_size = 16;
/* To make sure you use 16 everywhere,
* also easier to change it
*/
struct woo_item {
char n[woo_n_size];
char x;
};
struct s_woo {
struct woo_item *items;
size_t size; / * optinal, to keep track of item count */
}
With the woo_item struct you can make sure there is no x without n[woo_n_size] allocated, and vice versa.
You can remember the count of woo_items by having a designated null element to close each of your lists, or just store a size member in s_woo
If this is a beginner's question, my apologies - most of my programming has been in very high level langauges, and I have limited expertise in C. (This is the sort of thing I could do very easily in languages such as Matlab, Octave, Sage, Maxima etc, but for this I need the speed of C).
But anyway... I have an array whose size is set at run time with malloc:
int *A = malloc(m * sizeof(int));
where m is computed from some values provided by the user. I have a function "update" which updates the array (or, if you prefer, takes the array as input and returns another as output). This update function may be called upwards of 10^8 times.
So the function itself can't introduce the appropriately sized output array with malloc, or the memory will be used up. So, for example, I can't do this:
int * update(int *L) /* produces next iteration of L */
{
int *out = malloc(m * sizeof(int));
/* do some stuff with L and produce new array out */
return (out);
}
I've tried to make out a static variable outside the update function:
static int *out;
and define its size in main:
out = malloc(m * sizeof(int));
But this doesn't seem to work either.
Anyway, I would be very grateful of some advice - I think I've exhausted the excellence of google.
Allocate the array outside of update, then pass a pointer to it:
void update(int const *L, int *out)
{
// whatever
}
Call as
int *A = malloc(m * sizeof(int));
if (A == NULL)
// handle error
for (i=0; i < N_ITER; i++)
update(L, A);
Though you may want to redesign the program so that it updates L in-place.
So if you are simply wanting to work on the data that is coming into the function directly, then what you have is partially already correct. The only thing that I would do is to add the size of the array as an input parameter to the routine to look like this:
void update(int * L, unsigned int size){
unsigned int count;
// Make sure the array has actually been allocated from outside
if(L == NULL) return;
// Example work on L just as if it is an array of values
for(count = 0; count < size; count++){
L[count] = L[count] + 1;
}
}
REMEMBER, this will work if you DO NOT wish to maintain the original data within L. If you do wish to maintain the original data, then larsmans answer will work better for you.
Also remember that you will have to malloc whatever variable you wish to input into L, outside and prior to your update routine, and free at some other point.
int * myVar = (int *)malloc(m * sizeof(int));
update(myVar, m);
// Other work to be done
free(myVar);
You should use realloc.
int *a = realloc(a, m * sizeof(a[0]));
It will work just as malloc in the first run but then it will reallocate a different sized array. You should note that the new array might or might not have the previous values assigned in it. You should assume that it has garbage like all things given by malloc.
Here is a good explanation of using realloc.
http://www.java-samples.com/showtutorial.php?tutorialid=589
NOTE : sizeof(a[0]) is equal to sizeof int but if you change int it will still be right
I'm attempting to create a simple 2D array in C but apparently running into some memory trouble. My setup is simple enough and I can't tell what's wrong. I admit that my understanding of pointers is insufficient, but I still think this should be working. Can anyone see the flaw here?
typedef unsigned int DATUM;
DATUM **series_of_data;
void initialize_data()
{
*series_of_data = (DATUM *) malloc(1024 * sizeof(DATUM));
}
This causes my program to crash with a bus error when I run it.
series_of_data is actually not allocated.
You have various way to allocates a 2D array, either using the array of rows model whcih has bad cache coherency and thus has usually bad performances or to use the Iliffe vector adviced in Numerical recipes in C that consists in allocating one huge h*w memory block and a side pointer array which contains the beginning of your rows (or columns) :
DATUM** alloc_array( int h, int w )
{
int i;
DATUM** m = (DATUM**)malloc(h*sizeof(DATUM*));
m[0] = (DATUM*)malloc(h*w*sizeof(DATUM));
for(i=1;i<h;i++) m[i] = m[i-1]+w;
return m;
}
void release_array(DATUM** m)
{
free( m[0] );
free( m);
}
int main()
{
int r,c;
DATUM** tab;
int width = 5;
int height = 3;
tab = alloc_array(height, width); /* column first */
for(r = 0;r<height;++r)
for(c = 0;c<width;++c)
tab[r][c] = (1+r+c);
for(r = 0;r<height;++r)
{
for(c = 0;c<width;++c)
{
printf("%d\t",tab[r][c]);
}
puts("");
}
release_array(tab);
}
Data are nicely packed in memory, so cache are happy and you keep the [][] access pattern.
As a matter of speed this is in +/-3% speed of the classical DATUM* + polynomial access method.
series_of_data is an invalid pointer - you don't assign it to anything. When you try to assign to its memory location (*series_of_data = ...), it's putting stuff in a random place, which is likely to not do what you want. You have to point series_of_data somewhere useful, e.g.
series_of_data = (DATUM **)malloc(16 * sizeof(DATUM *))
for an array with 16 slots for DATUM * pointers in it.
You haven't allocated the series_of_data pointer before you assign to *series_of_data.
For example, if series_of_data is intended to be an array then you would need to write something like this:
series_of_data = malloc(n*sizeof(DATUM*));
where n is the length of the series_of_data array.
Only after you have done this can you assign to *series_of_data.
I'm still new to C, malloc, and all that jazz, so I decided to write this to learn some more skills. The idea is, I'm reading in a bunch of ints from a file and putting them into a matrix (2d array). The start of the file says how many rows and columns there are, so it reads those numbers in and uses malloc to set up the 2d array.
int read_matrix(FILE *mat, int ***Z, int *x, int *y)
{
int i = 0;
int x_temp = 0;
int y_temp = 0;
if (fscanf(mat, "%d %d", &(*x), &(*y)) == EOF){
printf("File is not big enough to contain a matrix\n");
return -1;
}
printf("About to malloc %d\n", *x);
*Z = (int**) malloc(*x * sizeof(int*));
while (i < *x) {
printf("mallocing %d\n", i);
*Z[i] = (int*) malloc(*y * sizeof(int));
printf("malloced\n");
++i;
}
printf("Malloc complete\n");
/*Other unimportant code*/
}
The output reads:
About to malloc 3
mallocing 0
malloced
mallocing 1
Segmentation fault
So it's not mallocing anything but one int** in Z.. I think?
I'm very new to C, so I'm not sure if I've made some little mistake, or if I'm really going about this whole thing incorrectly. Any thoughts? Thanks!
The [] operator binds more closely than the unary * operator. Try changing *Z[i] to (*Z)[i] and see if your code behaves.
As a side note, it's also quite common in C to malloc a single array of (sizex*sizey) size, for a matrix and then index it as arr[x*sizey + y] or arr[y*sizex + x]. That more closely mimics what the language does with static arrays (e.g. if you declare int foo[10][10], all 100 ints are contiguous in memory and nowhere is a list of 10 int*'s stored.
I agree with both Walter and AndreyT. This is just some additional information.
Note that you can get away with just two malloc() calls, rather than *x + 1 - one big block for the ints themselves, and one for the row index.
*Z = malloc(*x * sizeof (*Z)[0]);
(*Z)[0] = malloc(*x * *y * sizeof (*Z)[0][0]);
for (i = 1; i < *x; i++) {
(*Z)[i] = (*Z)[0] + i * *y;
}
As Walter correctly noted in his answer, it should be (*Z)[i] = ..., not *Z[i] = ....
On top of that I'd suggest getting rid of that dereference/typecast hell present in your source code. Don't cast the result of malloc. Don't use type names under sizeof. Expressing it as follows
*Z = malloc(*x * sizeof **Z);
...
(*Z)[i] = malloc(*y * sizeof *(*Z)[i]);
wil make your code type-independent and much more readable.
A separate question is what on Earth made you use &(*x) in fscanf. Is this some kind of bizarre coding standard?