Error releasing structure pointer using free - c

**Hi, technologists. I'm new here. This is my first time to ask questions here. Please forgive me if I have done something wrong. I hope you can be more patient with me. Thank you very much.
I've been studying PointersOnC. And then I had a little trouble writing exercises. The topic is to write a program to achieve matrix multiplication. I defined a structure and named it a matrix. There are variables x and y of type int in the matrix, x and y store the row and column values. The matrix also has a secondary pointer of type int to store the values in the matrix. I define a struct level pointer in the main function and allocate memory through the function. It then allocates the secondary pointer in the structure and stores the value in the secondary pointer. But I had a problem freeing memory. I first release the first level of the second level pointer, then release the second level pointer, and finally release the structure pointer. An error was reported while releasing the structure pointer. **
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct {
int x, y; // Rows and Columns
int** values; // Numbers in the matrix
} matrix;
// Initialization matrix
bool InitMatrix(matrix** m)
{
*m = (matrix*)malloc(sizeof(matrix*));
if (!*m)
return false;
(*m)->x = 0, (*m)->y = 0;
(*m)->values = NULL; // Secondary pointer
return true;
}
// Dynamic memory allocation two-dimensional array
bool mallocTowAry(matrix* m)
{
if (m->x == 0 || m->y == 0)
return false;
m->values = (int**)malloc(sizeof(int*) * m->x);
if (!m->values)
return false;
for (int i = 0; i < m->x; i++)
{
m->values[i] = (int*)malloc(sizeof(int) * m->y);
if (m->values[i] == NULL)
return false;
}
return true;
}
// Store the number of the matrix in the array
void assginTow(matrix* m)
{
for (int i = 0; i < m->x; i++)
{
printf("Please enter the elements in the i-th row, separated by spaces:\n");
for (int j = 0; j < m->y; j++)
scanf("%d", &m->values[i][j]);
}
}
// Initialize the secondary pointer in the structure
bool assginMatrix(matrix* m, int x, int y)
{
m->x = x, m->y = y;
if (!mallocTowAry(m))
return false;
assginTow(m);
return true;
}
// Print matrix
void showMatrix(matrix* m)
{
for (int i = 0; i < m->x; i++)
{
for (int j = 0; j < m->y; j++)
printf("%d ", m->values[i][j]);
printf("\n");
}
}
int main(int argc, char* args[])
{
matrix* m_1;
// Initialize the matrix, but without x and y
if (!InitMatrix(&m_1))
return 1;
int x, y;
printf("Please enter the row and column values, separated by spaces: \n");
// Read in x and y
scanf("%d %d", &x, &y);
if (!assginMatrix(m_1, x, y))
return 2;
showMatrix(m_1);
// Destroy the matrix
DestoryMatrix(&m_1);
return 0;
}

Related

Pass a 2D pointer array to function

I'm new to C programming and have to write a small program where I should do stuff with a matrix (Input and solve a list of equations stored in a 2D Matrix). Individually the different functions of the program (input the matrix, calculate the solution, output the matrix) are no problem. In this (shortened) version of the code, the void* getMatrix creates a matrix and assigns some values to each position in the matrix. I can access these in the main function with no problem.
But how can I pass this matrix (or better: a pointer to the matrix) to another function and access and edit it there?
I am not allowed to pass the values of the matrix, but instead have to use a pointer to the storage location of it.
Code:
#include <stdio.h>
#include <stdlib.h>
void* getMatrix(int *nPoint);
void doStuffWithMatrix(/*Pass matrix*/);
int main() {
int n = 8;
int *nPoint = &n;
float (*matrix)[*nPoint] = getPointer(nPoint);
//Print out the matrix
printf("\n");
for (int i = 0; i < *nPoint; i++) {
printf("| ");
for (int j = 0; j < *nPoint+1; j++) {
printf("%-5g | ", matrix[i][j]);
}
printf("\n");
}
doStuffWithMatrix(matrix);
free(*matrix);
}
void* getMatrix(int *nPoint) {
//Create 2D Matrix
float (*matrix)[*nPoint] = malloc(sizeof(float[*nPoint][*nPoint + 1]));
//Temporary value assign
for (int i = 0; i < *nPoint; i++) {
for (int j = 0; j < *nPoint+1; j++) {
matrix[i][j] = 10 * (i + 1) + (j + 1);
}
}
return matrix;
}
void printMatrix(/*Pass matrix*/) {
//Do Stuff
}
The function doStuffWithMatrix is just a placeholder and obviously doesn't work.
Note: I coded in Java before and thats why I put the { in the same line.
Return the address of first element of matrix in int* getMatrix and same can be passed into function by using Yourfunction(getMatrix(nPoint));

Storing data into a dynamic array with structs in C

I am having issues storing data from a file into my dynamic array. I am aware that what I have now is incorrect but it is just there for the moment. I have a file which on the first line contains the amount of lines of data essentially. The following lines have two integers side by side to represent an ordered pair. I want to store those two integers into a struct, point, that symbolizes an ordered pair. Also, the there is an array with such a struct that is inside of another struct, list , which contains the size of the array, or the amount of data currently stored in the array and a capacity which is the total amount of space in the array.
I want to store the two integers into variables of type int and then store them into a point inside of my array that is in my list struct.
I am getting very confused having two structs and am unsure if this is the correct approach. Any feedback would be welcomed.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *A;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point A[], int begin, int end, point p0)
{
point min = A[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(A[n], p0) < polarAngle(min, p0))
{
min = A[n];
where = n;
}
return where;
}
void selectionSort(point A[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(A, n, N, p0);
temp = A[n];
A[n] = A[s];
A[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->A[x] = p->A[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->A[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->A[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
point p0, P;
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
fscanf(input, "%d", &N);
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p = (point*)malloc(N*sizeof(point));
if (p == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
return -1;
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &P.x, &P.y);
p->A[n] = P.x;
p->A[n] = P.y;
}
fclose(input);
free(p);
return 0;
}
First of all, your code cannot be compiled because this
p->A[n] = P.x;
p->A[n] = P.y;
is wrong, it should be
p->A[n].x = P.x;
p->A[n].y = P.y;
because A has type point and you should access the members of the struct in order to assign values to them.
But this is just the begining of the problems, you didn't allocate space for the A pointer, so this will not work.
You need to allocate space for an instance of type list, which is done this way
p = malloc(sizeof(*p));
Then you need to initialize p's members, for which
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
as you see space was allocated for the values member.
Check fscanf() to insure data integrity and avoid undefined behavior, if fscanf() fails you would never know with your code and you potentially access uninitialized variables which leads to Undefined Behavior.
Capture the values scanned from the file in two int variables and copy them to the array only if the where sucessfuly read
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
/* check that the values were read from the file _______^ */
{
/* store them in the array */
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
Check that the file did open.
I suggest the following code
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *values;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point values[], int begin, int end, point p0)
{
point min = values[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(values[n], p0) < polarAngle(min, p0))
{
min = values[n];
where = n;
}
return where;
}
void selectionSort(point values[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(values, n, N, p0);
temp = values[n];
values[n] = values[s];
values[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->values[x] = p->values[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->values[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->values[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
if (input == NULL)
return -1;
if (fscanf(input, "%d", &N) != 1)
{
fclose(input);
return -1;
}
p = malloc(sizeof(*p));
if (p == NULL)
return -1;
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
if (p->values == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
{
free(p);
fclose(input);
return -1;
}
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
{
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
fclose(input);
free(p->values);
free(p);
return 0;
}
As you can see there is another improvement you can do to the code, it's not too important but it would avoid using the N and n variables which are not necessary.
Note: before using a function, try to read throughly it's documentation, that will prevent all sorts of unexpected results, for example fscanf(), will help you understand my fixes more.
The variable p should be list p.
The points array allocation is p.A = (point*)malloc(N*sizeof(point));
In the filling loop, since A[n] is a point you can't assign it the int P.x or P.y. You can directly put values into the A[n] point like that:
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &(p.A[n].x), &(p.A[N].y));
}
The size and capacity of the list should be initialized: p.capacity = N; right after succesfull memory allocation and p.capacity = n; after filling the array
And in the end you should call free(p.A) instead of free(p).

filling 2d array with mutiplicatio table

#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);
}
}
}

An array that increases in size as a loop continues C

I'm trying to generate an array that increases in size as a while loop iterates. I know a pointer has something to do with the solution. Please look at the code below.
#include <stdio.h>
int main () {
int x = 0;
int *F = malloc(sizeof(int)); //I want F to start out as :-
F[0] = 1; // 1 by 1
F[1] = 2; // 1 by 2 such that it increases in size when assigned
int now = 2;
int evenSum = 2;
while (x <= 40000) {
F[now] = F[now-1] + F[now-2];
x = F[now];
if (F[now] % 2)
{
evenSum += F[now];
}
++now;
}
printf("The outcome is %d\n", evenSum);
//free(F);
// Yes this is problem 2 of euler challenge, i already got a working static model
}
Many Thanks in Advance
EDIT
What I'm actually looking for is the sum of all the even fib's up to a cut off limit of 40M. I could (what i did first time) sum the even numbers as i encounter them during the fib sequence. This meant i did not keep a array of some arbitary size. The purpose of this post is to create a growing memory that just keeps on consuming memory until it gets to the answer.
The following is the code I got from the brilliant answer that was given.
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
struct vector {
size_t size;
int *data;
};
void vector_resize(struct vector *vector, size_t size) {
if (vector->size >= size)
return;
while (vector->size < size)
vector->size *= 2;
vector->data = realloc(vector->data, sizeof(int) * vector->size);
assert(vector->data != NULL);
}
struct vector * vector_init() {
struct vector *vector = malloc(sizeof(*vector));
vector->size = 4;
vector->data = malloc(vector->size * sizeof(int));
return vector;
}
void vector_free(struct vector *vector) {
free(vector->data);
free(vector);
}
void vector_put(struct vector *vector, size_t index, int data) {
vector_resize(vector, index+1);
vector->data[index] = data;;
}
int vector_get(struct vector *vector, size_t index) {
vector_resize(vector, index+1);
return vector->data[index];
}
int main() {
struct vector *vector = vector_init();
int fibNow = 0;
int now = 2;
vector_put(vector, 0, 1);
vector_put(vector, 1, 2);
int evenSum = 2;
while (fibNow <= 4000000) {
fibNow = vector_get(vector, (now-1)) + vector_get(vector, (now-2));
vector_put(vector, now, fibNow);
if (fibNow % 2 == 0) {
evenSum += fibNow;
}
++now;
}
printf("The outcome is %d\n", evenSum);
// vector_put(vector, 0, 5);
// vector_put(vector, 9, 2);
// int i;
// for (i=0; i<10; ++i)
// printf("index 0: %d\n", vector_get(vector, i));
vector_free(vector);
}
So, In C we aren't allowed to overload the operator[]. But we could still create an object that functions like your request:
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
struct vector {
size_t size;
int *data;
};
void vector_resize(struct vector *vector, size_t size) {
if (vector->size >= size)
return;
while (vector->size < size)
vector->size *= 2;
vector->data = realloc(vector->data, sizeof(int) * vector->size);
assert(vector->data != NULL);
}
struct vector * vector_init() {
struct vector *vector = malloc(sizeof(*vector));
vector->size = 4;
vector->data = malloc(vector->size * sizeof(int));
return vector;
}
void vector_free(struct vector *vector) {
free(vector->data);
free(vector);
}
void vector_put(struct vector *vector, size_t index, int data) {
vector_resize(vector, index+1);
vector->data[index] = data;;
}
int vector_get(struct vector *vector, size_t index) {
vector_resize(vector, index+1);
return vector->data[index];
}
int main() {
struct vector *vector = vector_init();
vector_put(vector, 0, 5);
vector_put(vector, 9, 2);
for (int i=0; i<10; ++i)
printf("index 0: %d\n", vector_get(vector, i));
vector_free(vector);
}
Additionally, it's fun to look at a C++ version of what this could be. C++ makes this look far more like your original code, because we can overload operator[] for arbitrary objects.
#include <cstdio>
#include <vector>
template <typename T>
class auto_growing_vector {
private:
std::vector<T> data;
public:
T & operator[](size_t index) {
if (index >= data.size())
data.resize(index + 1);
return data[index];
}
};
int main() {
auto_growing_vector<int> vector;
vector[0] = 5;
vector[9] = 2;
for (int i=0; i<10; ++i)
printf("index 0: %d\n", vector[i]);
}
In general, realloc should do the trick for you. Example (this is just a snippet - you will need to do the rest yourself):
int *F;
F = malloc(2 * sizeof *F); // note you have to start with 2 elements for your code, not 1
F[0] = 1;
F[1] = 2;
// when you know you need to increase the size of F:
temp = realloc(F, n * sizeof *F); // where n is the new size in elements
if(temp != NULL) F = temp; // note that the block may have moved to a new place!
else {
printf("unable to grow the array to %d elements!\n", n);
free(F);
exit(0);
}
Of course for this problem you don't need to keep all the Fibonacci numbers - just the last two. This actually suggests a much simpler code. Let me start if for you, and see if you can finish it (since you are doing the Euler problems, which are all about figuring it out for yourself):
int first = 1;
int second = 1; // usually you start with 1,1,2,3,...
int temp, current;
int count;
int N = 4000; // where we stop
for(count = 2; count < N; count ++) {
current = first + second;
first = second;
second = current;
}
If you look closely, you can get even more efficient that this (hint, you really only need to keep one older value, not two...)
Reading the comments, if you want all the numbers in memory, you should just allocate enough space from the outset:
F = malloc(4000 * sizeof *F);
and no further manipulations are needed. Make sure your last index is 3999 in that case (since arrays are zero indexed).
I One way would be to use 2D array int[n][n], whith a lot of unused space
II Easier way would be to expend array size in every iteration by realocate function.
Just in that case, either:
a) every element of the original array would be a pointer to a new array of length i (i beeing iteration number), you would then realocate the original array to make size for new pointer, then allocate i*sizeof(int) of new memory for that new array that pointer would point to.
b) You would make linearized traingular matrix in which the original array will hold just numbers, not pointers. In every iteration you would expand it's size for i new elements. Linearized trangular matrix is a onedimensional array of numbers in which data is saved like this:
ordinary matrix: (/ = wasted memory)
A///
BC//
DEF/
GHIJ
linarized triangular matrix
ABCDEFGHIJ
You can acces linerized triangular matrix element E with coordinates [y,x] = [2,1] (element 'A' taken for origin) like
sum=0;
for(iy=0;iy<y;iy++)
for(ix=0;ix<=y && ix<x;ix++) sum++;
//myLinMatr[sum]=='E'

Removing Duplicates from an Array using C [duplicate]

This question already has answers here:
Algorithm: efficient way to remove duplicate integers from an array
(34 answers)
Closed 8 years ago.
I want small clarification in array concept in C.
I have array:
int a[11]={1,2,3,4,5,11,11,11,11,16,16};
I want result like this:
{1,2,3,4,5,11,16}
Means I want remove duplicates.
How is it possible?
You can't readily resize arrays in C - at least, not arrays as you've declared that one. Clearly, if the data is in sorted order, it is straight-forward to copy the data to the front of the allocated array and treat it as if it was of the correct smaller size (and it is a linear O(n) algorithm). If the data is not sorted, it gets messier; the trivial algorithm is quadratic, so maybe a sort (O(N lg N)) followed by the linear algorithm is best for that.
You can use dynamically allocated memory to manage arrays. That may be beyond where you've reached in your studies, though.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static int intcmp(const void *pa, const void *pb)
{
int a = *(int *)pa;
int b = *(int *)pb;
if (a > b)
return +1;
else if (a < b)
return -1;
else
return 0;
}
static int compact(int *array, int size)
{
int i;
int last = 0;
assert(size >= 0);
if (size <= 0)
return size;
for (i = 1; i < size; i++)
{
if (array[i] != array[last])
array[++last] = array[i];
}
return(last + 1);
}
static void print(int *array, int size, const char *tag, const char *name)
{
int i;
printf("%s\n", tag);
for (i = 0; i < size; i++)
printf("%s[%d] = %d\n", name, i, array[i]);
}
int main(void)
{
int a[11] = {1,2,3,4,5,11,11,11,11,16,16};
int a_size = sizeof(a) / sizeof(a[0]);
print(a, a_size, "Before", "a");
a_size = compact(a, a_size);
print(a, a_size, "After", "a");
int b[11] = {11,1,11,3,16,2,5,11,4,11,16};
int b_size = sizeof(b) / sizeof(b[0]);
print(b, b_size, "Before", "b");
qsort(b, b_size, sizeof(b[0]), intcmp);
print(b, b_size, "Sorted", "b");
b_size = compact(b, b_size);
print(b, b_size, "After", "b");
return 0;
}
#define arraysize(x) (sizeof(x) / sizeof(x[0])) // put this before main
int main() {
bool duplicate = false;
int a[11] = {1,2,3,4,5,11,11,11,11,16,16}; // doesnt have to be sorted
int b[11];
int index = 0;
for(int i = 0; i < arraysize(a); i++) { // looping through the main array
for(int j = 0; j < index; j++) { // looping through the target array where we know we have data. if we haven't found anything yet, this wont loop
if(a[i] == b[j]) { // if the target array contains the object, no need to continue further.
duplicate = true;
break; // break from this loop
}
}
if(!duplicate) { // if our value wasn't found in 'b' we will add this non-dublicate at index
b[index] = a[i];
index++;
}
duplicate = false; // restart
}
// optional
int c[index]; // index will be the number of objects we have in b
for(int k = 0; k < index; k++) {
c[k] = b[k];
}
}
If you really have to you can create a new array where that is the correct size and copy this into it.
As you can see, C is a very basic (but powerful) language and if you can, use a vector to but your objects in instead (c++'s std::vector perhaps) which can easily increase with your needs.
But as long as you only use small numbers of integers you shouldn't loose to much. If you have big numbers of data, you can always allocate the array on the heap with "malloc()" and pick a smaller size (maybe half the size of the original source array) that you then can increase (using realloc()) as you add more objects to it. There is some downsides reallocating the memory all the time as well but it is a decision you have to make - fast but allocation more data then you need? or slower and having the exact number of elements you need allocated (which you really cant control since malloc() might allocate more data then you need in some cases).
//gcc -Wall q2.cc -o q2 && q2
//Write a program to remove duplicates from a sorted array.
/*
The basic idea of our algorithm is to compare 2 adjacent values and determine if they
are the same. If they are not the same and we weren't already looking previusly at adjacent pairs
that were the same, then we output the value at the current index. The algorithm does everything
in-place and doesn't allocate any new memory. It outputs the unique values into the input array.
*/
#include <stdio.h>
#include <assert.h>
int remove_dups(int *arr, int n)
{
int idx = 0, odx = -1;
bool dup = false;
while (idx < n)
{
if (arr[idx] != arr[idx+1])
{
if (dup)
dup = false;
else
{
arr[++odx] = arr[idx];
}
} else
dup = true;
idx++;
}
return (odx == -1) ? -1 : ++odx;
}
int main(int argc, char *argv[])
{
int a[] = {31,44,44,67,67,99,99,100,101};
int k = remove_dups(a,9);
assert(k == 3);
for (int i = 0;i<k;i++)
printf("%d ",a[i]);
printf("\n\n");
int b[] = {-5,-3,-2,-2,-2,-2,1,3,5,5,18,18};
k = remove_dups(b,12);
assert(k == 4);
for (int i = 0;i<k;i++)
printf("%d ",b[i]);
printf("\n\n");
int c[] = {1,2,3,4,5,6,7,8,9};
k = remove_dups(c,9);
assert(k == 9);
for (int i = 0;i<k;i++)
printf("%d ",c[i]);
return 0;
}
you should create a new array and you should check the array if contains the element you want to insert before insert new element to it.
The question is not clear. Though, if you are trying to remove duplicates, you can use nested 'for' loops and remove all those values which occur more than once.
C does not have a built in data type that supports what you want -- you would need to create your own.
int a[11]={1,2,3,4,5,11,11,11,11,16,16};
As this array is sorted array, you can achieve very easily by following code.
int LengthofArray = 11;
//First elemnt can not be a duplicate so exclude the same and start from i = 1 than 0.
for(int i = 1; i < LengthofArray; i++);
{
if(a[i] == a[i-1])
RemoveArrayElementatIndex(i);
}
//function is used to remove the elements in the same as index passed to remove.
RemoveArrayElementatIndex(int i)
{
int k = 0;
if(i <=0)
return;
k = i;
int j =1; // variable is used to next item(offset) in the array from k.
//Move the next items to the array
//if its last item then the length of the array is updated directly, eg. incase i = 10.
while((k+j) < LengthofArray)
{
if(a[k] == a[k+j])
{
//increment only j , as another duplicate in this array
j = j +1 ;
}
else
{
a[k] = a[k+j];
//increment only k , as offset remains same
k = k + 1;
}
}
//set the new length of the array .
LengthofArray = k;
}
You could utilise qsort from stdlib.h to ensure your array is sorted into ascending order to remove the need for a nested loop.
Note that qsort requires a pointer to a function (int_cmp in this instance), i've included it below.
This function, int_array_unique returns the duplicate free array 'in-place' i.e. it overwrites the original and returns the length of the duplicate free array via the pn pointer
/**
* Return unique version of int array (duplicates removed)
*/
int int_array_unique(int *array, size_t *pn)
{
size_t n = *pn;
/* return err code 1 if a zero length array is passed in */
if (n == 0) return 1;
int i;
/* count the no. of unique array values */
int c=0;
/* sort input array so any duplicate values will be positioned next to each
* other */
qsort(array, n, sizeof(int), int_cmp);
/* size of the unique array is unknown at this point, but the output array
* can be no larger than the input array. Note, the correct length of the
* data is returned via pn */
int *tmp_array = calloc(n, sizeof(int));
tmp_array[c] = array[0];
c++;
for (i=1; i<n; i++) {
/* true if consecutive values are not equal */
if ( array[i] != array[i-1]) {
tmp_array[c] = array[i];
c++;
}
}
memmove(array, tmp_array, n*sizeof(int));
free(tmp_array);
/* set return parameter to length of data (e.g. no. of valid integers not
* actual allocated array length) of the uniqe array */
*pn = c;
return 0;
}
/* qsort int comparison function */
int int_cmp(const void *a, const void *b)
{
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
/* integer comparison: returns negative if b > a
and positive if a > b */
return *ia - *ib;
}
Store the array element with small condition into new array
**just run once 100% will work
!)store the first value into array
II)store the another element check with before stored value..
III)if it exists leave the element--and check next one and store
here the below code run this u will understand better
int main()
{
int a[10],b[10],i,n,j=0,pos=0;
printf("\n enter a n value ");
scanf("%d",&n);
printf("\n enter a array value");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//gets the arry value
}
for(i=0;i<n;i++)
{
if(check(a[i],pos,b)==0)//checks array each value its exits or not
{
b[j]=a[i];
j++;
pos++;//count the size of new storing element
}
}
printf("\n after updating array");
for(j=0;j<pos;j++)
{
printf("\n %d",b[j]);
} return 0;
}
int check(int x,int pos,int b[])
{ int m=0,i;
for(i=0;i<pos;i++)//checking the already only stored element
{
if(b[i]==x)
{
m++; //already exists increment the m value
}
}
return m;
}

Resources