Adding binary numbers in C - c

Im getting the error "invalid operands to binary + (have int* and int*)" and i don't know why It is throwing me this error. how would I go about adding the array elements of the 2 arrays. note both arrays are the same size.
int* complement2_add(int* first_complement2[], int* second_compelment[], int size){
int count = 0,remainder = 0, carryover = 0;
int* cAdd = (int*)malloc(size*sizeof(int));
for(count = size-1; count >= 0; count--){
remainder = first_complement2[count] + second_compelment[count] + carryover;
if(remainder == 1){
cAdd[count] = 1;
carryover = 0;
}
else if(remainder == 2){
cAdd[count] = 0;
carryover = 1;
}
else if(remainder == 3){
cAdd[count] = 1;
carryover = 1;
}
else if(remainder == 0){
cAdd[count] =0;
carryover = 0;
}
}
if(carryover == 1){
cAdd[count] = 1;
}
return cAdd;
}
Then I am calling the function in main like this.
int* add1 = complement_2_add(complement2Array1, complement2Array2, j);
Complement2Array1 and Complement2Array2 are defined the same.
int* complement2Array1 = signed2complement2(signedIntArray1, j);
and signed2complement2 is defined as.
int* signed2complement2(int signed_binary[], int size){
int i = 0;
int* complemt2Array = (int*)malloc(size*sizeof(int));
int flipflag = 0;
for(i = size-1; i>=0;i-- ){
if(flipflag == 0){
complemt2Array[i] = signed_binary[i];
if(signed_binary[i] == 1){
flipflag = 1;
}
}
else{
complemt2Array[i] = signed_binary[i] == 0?1:0;
}
}
return complemt2Array;
}

remainder = first_complement2[count] + second_compelment[count] + carryover;
In this first_complement2[count] , second_compelment[count] both are integer pointers .
As both first_complement and second_complement are array of integer pointers.
You need to dereference them before adding -
remainder = (*first_complement2[count]) + (*second_compelment[count]) + carryover;
EDIT
Didn't you got any warning or error for passing a int * to a function which expects array of integer pointer or int ** ?
int* complement2Array1 = signed2complement2(signedIntArray1, j); // it is an int *
complement2Array1 and complement2array2 has to be of type int ** or to be array of int pointers.
Or simple as #alk Sir suggested use int * instead of int **.

This
int* complement2_add(int* first_complement2[], int* second_compelment[], int size){
if equal to
int* complement2_add(int ** first_complement2, int ** second_compelment, int size){
which from the way you use first_complement2 and second_compelment and the way you call complement2_add() is wrong.
It seems you wanted
int* complement2_add(int * first_complement2, int * second_compelment, int size){
Also add the prototype to it before it is used:
int* complement2_add(int * first_complement2, int * second_compelment, int size);
... somefunc(...)
{
...
int* add1 = complement_2_add(complement2Array1, complement2Array2, j);
...
}
int* complement2_add(int* first_complement2, int* second_compelment, int size)
{
int count = 0,remainder = 0, carryover = 0;
...

Related

Cannot access to memory in C

I have to create a function that initializes k cluster choosing the starting center based on the distance between the point.
This is the code i wrote:
int *inizialize_centroids(int *p_dataset, int d, int k, int **p_discard_set) {
int* centroids = (int*) malloc(k*((2*d)+1)*sizeof(int)), *point_to_compare = (int*) malloc(d*sizeof(int)),
*cluster_point = (int*) malloc(d*sizeof(int));
float* distance = (float*) malloc(2*k*sizeof(float));
if(centroids == NULL || point_to_compare == NULL || cluster_point == NULL || distance == NULL){
printf("Something went wrong in inizialize_centroids(), memory allocation failed! (row 94/95)");
exit(1);
}
centroids[0]=1;
for(int i = 1; i < d; i++){
centroids[i] = p_dataset[i];
centroids[i+d] = pow(p_dataset[i],2);
}
*p_discard_set[0] = 1;
*p_discard_set[1] = p_dataset[0];
memcpy(cluster_point, &p_dataset[0], (d + 1)*sizeof(int));
int j;
int i = 1;
int t;
while (i < k){
j = 0;
while(j < 2*CHUNK ){
memcpy(point_to_compare, &p_dataset[j/2 * (d + 1)], (d + 1) * sizeof(int));
distance[j] = (float) point_to_compare[0];
j++;
distance[j] = compare(cluster_point, point_to_compare, i, d);
j++;
}
int id = (int) distance[0];
float max = distance[1];
j = 0;
while (j < 2* CHUNK){
if(distance[j+1] > max){
max = distance[j+1];
id = distance[j];
}
j+=2;
}
i++;
*p_discard_set[0] = i;
*p_discard_set[i] = id; //HERE OCCURE THE PROBLEM
[....]
}
return centroids;
The problem is that, i can't assign
*p_discard_set[i] = id;
and i don't understand why it gives me "interrupted by signal 11: SIGSEGV"
This is how i use it in main:
int *discard_set = (int*) malloc((k + 1) * sizeof(int)), *compressed_set = (int*) malloc(sizeof(int)), *retained_set = (int*) malloc(sizeof(int));
// discard_set è così fatto: [n, id_1, ... , id_n]
if(discard_set == NULL || compressed_set == NULL || retained_set == NULL){
printf("Something went wrong in main(), memory allocation failed! (row 39)");
exit(1);
}
int* centroids = inizialize_centroids(dataset, d, k, &discard_set);
The stange thing is that i can do
*p_discard_set[0] = i;
and k > 2, so it isn't out of bound, I think.
The precedence of postfix operators in C is higher than prefix, so when you say
*p_discard_set[i] = ...
you actually get
*(p_discard_set[i]) = ...
and what you actually want is
(*p_discard_set)[i] = ...
so you need the explicit parentheses to make it work the way you are expecting.

Why is this below code giving heap overflow Error by just changing the comparison operator from &&(AND) to ||(OR)?

I was trying to solve below problem:
Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in any order.
Example 1:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]
Here is my code:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
for(int i=0; i<nums1Size-1; i++){
if(nums1[i]>nums1[i+1]){
int temp = nums1[i];
nums1[i] = nums1[i+1];
nums1[i+1] = temp;
i = -1;
}
}
for(int i=0; i<nums2Size-1; i++){
if(nums2[i]>nums2[i+1]){
int temp = nums2[i];
nums2[i] = nums2[i+1];
nums2[i+1] = temp;
i = -1;
}
}
int i = 0;
int j = 0;
int* res = (int*)malloc(10* sizeof(int));
int k = 0;
if(!(nums1Size > nums2Size)){
int * temp = nums1;
nums1 = nums2;
nums2 = temp;
int tempint = nums1Size;
nums1Size = nums2Size;
nums2Size = tempint;
}
while(i<nums1Size && j<nums2Size){
if(nums1[i] > nums2[j]){
j++;
}
else if(nums1[i] < nums2[j]){
i++;
}
else{
res[k++] = nums1[i];
i++; j++;
}
}
*returnSize = sizeof(res)/sizeof(res[0]);
return res;
}
To simplify the problem you have to solve, let's first write a helper function that counts the number of occurrences of a particular element inside an array:
int count_elem(int* arr, int n, int elem) {
int count = 0;
for (int i = 0; i < n; i += 1) {
if (arr[i] == elem) {
count += 1;
}
}
return count;
}
Now, let's try to solve the problem following the problem description:
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
// here we allocate `res` with size of the biggest array, because that's the worst case we'll have
int* res = malloc(sizeof(int) * ((nums1Size > nums2Size) ? nums1Size : nums2Size));
// just to be sure `malloc()` did not return an error
if (res == NULL) {
return NULL;
}
// we'll keep track of how many elements we actually put inside `res`
*returnSize = 0;
// let's loop through all elements of `nums1`
for (int i = 0; i < nums1Size; i += 1) {
int elem = nums1[i];
// if we already put the element inside `res`, we skip this cycle
int count_res = count_elem(res, *returnSize, elem);
if (count_res > 0) {
continue;
}
// let's count the occurrences in both arrays
int count1 = count_elem(nums1, nums1Size, elem);
int count2 = count_elem(nums2, nums2Size, elem);
// let's calculate how many times the element must be present inside `res`
// i.e.: the same number of times of the array with the fewer occurrences of it
// NOTE: if `nums1` or `nums2` do not include the element, we also don't include it inside `res`
int count_min = (count1 < count2) ? count1 : count2;
// now let's put inside `res` as many times as we previously calculated
for (int i = 0; i < count_min; i += 1) {
res[*returnSize] = elem;
*returnSize += 1;
}
}
return res;
}
Let's try if it works:
int main(void) {
int arr1[] = {1, 2, 2, 1};
int arr2[] = {2, 2};
int res_size;
int* res = intersect(arr1, sizeof(arr1) / sizeof(arr1[0]), arr2, sizeof(arr2) / sizeof(arr2[0]), &res_size);
// let's print the result of `intersect()`
for (int i = 0; i < res_size; i += 1) {
printf("%d\n", res[i]);
}
return 0;
}
Output:
2
2
NOTE: the function is not optimized for speed nor for memory efficiency. This will be left as an exercise for the reader.
UPDATE
The previous version of the answer was wrong (sorry again). Now it should be correct.

Why does the point crash when free it?

In the following code, the result is ok, but the code will be crash when executing finish, and increase one error: Heap corruption detected, the free list is damaged at 0x600000008f50
int *mergeSort(int *a,int count) {
int leftCount = count / 2;
int rightCount = count - leftCount;
int *leftData = getData(a, 0, leftCount);
int *rightData = getData(a, leftCount, count);
int *sortedLeftData = mergeSort(leftData, leftCount);
int *sortedRightData = mergeSort(rightData, rightCount);
int *resultData = mergeData(sortedLeftData, sortedRightData, leftCount,
rightCount);
return resultData;
}
int *getData(int *a,int from, int to) {
if (from > to) { return nil; }
int *res = malloc(to - from + 1);
for (int index = from; index < to; index ++) {
int value = a[index];
res[index-from] = value;
}
return res;
}
int *mergeData(int *a, int *b, int acount, int bcount) {
int *result = malloc(acount + bcount);
int aindex,bindex,rindex;
aindex = bindex = rindex = 0;
while (aindex < acount | bindex < bcount) {
int value,avalue = INT_MAX,bvalue = INT_MAX;
if (aindex < acount) { avalue = a[aindex]; }
if (bindex < bcount) { bvalue = b[bindex]; }
// get value from a point.
if (avalue <= bvalue) {
value = avalue;
aindex ++;
}else {
// get value from b point.
value = bvalue;
bindex ++;
}
result[rindex] = value;
rindex ++;
}
return result;
}
I don't understand why does crash when free the point, any answer will helpfull, thanks.
All of your allocations are too small, and thus you are overflowing your buffers.
The malloc function allocates the requested number of bytes. You need to multiply the number of elements you require by sizeof(int) if your elements are int type. e.g.
int *result = malloc((acount + bcount) * sizeof(int));
Other potential problems I spotted while reading your code are:
Using the bitwise-or operator instead of logical-or:
while (aindex < acount | bindex < bcount)
// ^ should be ||
You never free your temporary buffers, thus your program will blow out memory by leaking like crazy. You must free leftData, rightData, sortedLeftData and sortedRightData in the mergeSort function after you are finished with them.
Note that merge sort actually does not require so much allocation. Doing so will have a huge impact on performance. An efficient implementation only requires a single additional buffer for scratch operations, which can be allocated at the beginning.
I did implementation merge sort use single buffer, as the following code:
void mergeSort(int *a, int count) {
int *tempBuffer = malloc(count * sizeof(int));
mergeSortWithBuffer(a, 0, 0, count - 1,tempBuffer);
free(tempBuffer);
}
void mergeSortWithBuffer(int *a, int leftStart, int rightStart, int end, int *tempBuffer) {
int leftCount = rightStart - leftStart;
int rightCount = end - rightStart + 1;
if (leftCount + rightCount <= 1) { return; }
if (leftCount != 0) {
// left dichotomy
int lls = leftStart;
int lrs = leftStart + leftCount/2;
int lnd = rightStart - 1;
mergeSortWithBuffer(a, lls, lrs, lnd,tempBuffer);
}
if (rightCount != 0) {
// right dichotomy
int rls = rightStart;
int rrs = rightStart + rightCount/2;
int rnd = end;
mergeSortWithBuffer(a, rls, rrs, rnd,tempBuffer);
}
mergeData(a, leftStart, rightStart, end, tempBuffer);
}
void mergeData(int *a, int leftStart, int rightStart, int end,int *tempBuffer) {
int leftCount = rightStart - leftStart;
int rightCount = end - rightStart + 1;
int lindex,rindex;
lindex = rindex = 0;
while (lindex < leftCount || rindex < rightCount) {
int lv = INT_MAX,rv = INT_MAX;
if (lindex < leftCount) { lv = a[leftStart + lindex]; }
if (rindex < rightCount) { rv = a[rightStart + rindex]; }
if (lv <= rv) {
tempBuffer[leftStart + lindex + rindex] = lv;
lindex ++;
}else {
tempBuffer[leftStart + lindex + rindex] = rv;
rindex ++;
}
}
for (int index = 0; index < end - leftStart + 1; index ++) {
a[leftStart + index] = tempBuffer[leftStart + index];
}
}
I thought the mergeData function can replace data in the point a each other without the temp buffer, but the logic is too complex and the efficient is not fast, so i add the temp buffer in this function.
Would you have better suggestions if you have willing?

How to return a `realloc` array in C function

I want to append numbers to an empty array and the amount of these numbers is unknown at the start. For example, generating numbers from 1 to 10 and appending one after another.
generateFromOneToTen will save my result in output and count should be 10 after execution. Everything's alright if I print the result in this function.
int generateFromOneToTen(int *output, int count)
{
for (int i = 0; i < 10; i++) {
output = arrayAppendInt(output, i + 1, count);
count++;
}
// Print result of `output` is 1,2,3...10 here
return count;
}
And I implemented arrayAppendInt to dynamic increase the length of an array and append new value after the old ones.
int *arrayAppendInt(int *array, int value, int size)
{
int newSize = size + 1;
int *newArray = (int*) realloc(array, newSize * sizeof(int));
if (newArray == NULL) {
printf("ERROR: unable to realloc memory \n");
return NULL;
}
newArray[size] = value;
return newArray;
}
Here comes the question. When invoking the generation function, numbers will always be NULL. How can I return the generated numbers to the numbers variable?
int *numbers = NULL;
int count = 0;
count = generateFromOneToTen(numbers, 0);
^^^^^^^
You could use a pointer to a pointer of integer (int **):
int generateFromOneToTen(int **output, int count)
{
for (int i = 0; i < 10; i++) {
*output = arrayAppendInt(*output, i + 1, count);
count++;
}
// `*output` is 1,2,3...10 here
return count;
}
You could re-write the arrayAppendInt function like that:
int *arrayAppendInt(int *array, int value, int size)
{
int newSize = size + 1;
int *newArray;
if (array==NULL)
newArray = (int*) malloc ((1+size) * sizeof(int));
else
newArray = (int*) realloc(array, newSize * sizeof(int));
if (newArray == NULL) {
printf("ERROR: unable to realloc memory \n");
return NULL;
}
newArray[size] = value;
return newArray;
}
And call it like that *output = arrayAppendInt(*output, i + 1, i);.
The cleanest solution is (in my opinion) to pack the array+the bookkeeping (size,used) into a structure, and use (a pointer to) this structure as an argument.
#include <stdlib.h>
struct dopedarray {
unsigned size;
unsigned used;
int *array;
};
Now you can put all your allocation and bookkkeeping stuff into a single function (which can be inlined) :
int array_resize(struct dopedarray *ap, unsigned newsize)
{
int *newp;
if(!ap) return -1;
newp = realloc (ap->array, newsize*sizeof*ap->array);
// check return value here...
if (!newp) return -1;
free(ap->array);
ap->array = newp;
ap->size = newsize;
// bookkeeping sanity
if(ap->size > ap->used ) { ap->used > ap->size; }
return 0;
}
The add_element function needs to be changed a bit, too:
int array_add_element(struct dopedarray *ap, int value)
{
if(ap->used >= ap->size){
unsigned newsz;
newsz= ap->used ? 2*ap->used: 4;
array_resize(ap, newsz);
// check return value here...
}
ap->array[ap->used++] = val;
return 0;
}
The complete code to my question:
int generateFromOneToTen(int **output, int count) // +
{
for (int i = 0; i < 10; i++) {
*output = arrayAppendInt(*output, i + 1, count); // ++
count++;
}
return count;
}
int *arrayAppendInt(int *array, int value, int size)
{
int newSize = size + 1;
int *newArray = (int*) realloc(array, newSize * sizeof(int));
if (newArray == NULL) {
printf("ERROR: unable to realloc memory \n");
return NULL;
}
newArray[size] = value;
return newArray;
}
int *numbers = NULL;
int count = 0;
count = generateFromOneToTen(&numbers, 0); // +
This answer also worths reading: https://stackoverflow.com/a/9459803/1951254

Using a structure in a recursive function (referenced structure)

I'm having problems understanding how to write code that solves the following problem: I have a structure containing a 2D-array. Then I have a recursive function that take a pointer to the structure as an argument and I want the recursive function to be able to manipulate the structure sent, not a local copy.
The struct is initialized in the function initStruct, where memory for the 2D-array is allocated. The recursive function builds up an array and at a specific point calls a function to insert it into the structure's array.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int** spBasis(int);
void mpBasis(int**, int, int, int, int, int, int, int*, struct mpBasis *, int, int);
void initMpBasis(struct mpBasis *, int, int);
void insertMpState(struct mpBasis *, int *);
struct mpBasis {
int** basis;
int size;
int capacity;
};
int main() {
int a, b, c, d;
char maxE[256];
char noParticles[256];
char P[256];
char M[256];
FILE *fp;
int **spStates;
struct mpBasis *mp;
int mpState[6] = {0, 0, 0, 0, 0, 0};
printf("Input max e for sp states, no of particles, parity (1 for odd and 0 for even) and magnetic projection: ");
gets(maxE);
gets(noParticles);
gets(P);
gets(M);
spStates = spBasis(atoi(maxE));
fp = fopen("spStates.txt", "a+");
fprintf(fp, "E\tj\tl\tm\n");
for (a = 0; a < 330; a++) {
fprintf(fp, "State %d: ", a+1);
for (b = 0; b < 4; b++) {
fprintf(fp, "%d\t", spStates[a][b]);
}
fprintf(fp, "\n");
}
mp = malloc(sizeof(struct mpBasis));
initMpBasis(mp, 5449, 6);
for (c = 0; c < 5449; c++) {
for (d = 0; d < 6; d++) {
fprintf(fp, "%d: %d\t", c, mp->basis[c][d]);
}
fprintf(fp, "\n");
}
printf("%p\n", (void*) mp);
printf("hello 3");
mpBasis(spStates, 0, atoi(maxE), 0, atoi(M), 0, atoi(P), mpState, mp, 0, 0);
fclose(fp);
return 0;
}
int** spBasis(int maxE) {
int c;
int i, j, k, l;
int q = 0;
int** spStates;
spStates = (int**)malloc(330 * sizeof(int *));
for (c = 0; c < 330; c++) {
spStates[c] = malloc(4 * sizeof(int));
}
for (i = 0; i <= maxE; i++) {
for (j = i % 2; j <= i; j += 2) {
for (k = -(2 * j + 1); k <= (2 * j + 1); k += 2) {
spStates[q][0] = i;
spStates[q][1] = j;
spStates[q][2] = 2 * j + 1;
spStates[q][3] = k;
q += 1;
}
for (l = -(2 * j - 1); l <= (2 * j - 1); l += 2) {
spStates[q][0] = i;
spStates[q][1] = j;
spStates[q][2] = 2 * j - 1;
spStates[q][3] = l;
q += 1;
}
}
}
return spStates;
}
void mpBasis(int** spStates, int e, int maxE, int m, int M, int l,
int P, int * mpState, struct mpBasis *mpB, int position, int lastSpState) {
int i;
for (i = lastSpState; i < 330; i++) {
if (e > maxE) {
break;
} else if (position == 5) {
if (m == M && l % 2 == P) {
insertMpState(mpB, mpState);
break;
}
} else {
// add spState to mpState and make the recursive call for the next position
mpState[position] = i;
mpBasis(spStates, e + spStates[i][0], maxE, m + spStates[i][3], M,
l + spStates[i][1], P, mpState, mpB, position+1, i);
}
}
}
void initMpBasis(struct mpBasis *a, int initialSize, int sizeY) {
int c;
a->basis = (int **)malloc(initialSize * sizeof(int*));
for (c = 0; c < initialSize; c++) {
a->basis[c] = (int *) malloc(sizeY * sizeof(int));
}
a->size = 0;
a->capacity = initialSize;
}
void insertMpState(struct mpBasis *a, int* mpState) {
/*if (a->size == a->capacity) {
a->size *= 2;
a->basis = (int **)realloc(a->basis, a->size * sizeof(int));
}*/
a->basis[a->size++] = mpState;
}
Added all the code.
The problem is that after the recursive function has been called, the "basis" array in structure mpBasis still only contains random values, i.e. the mpBasis function hasn't done anything with it. Am I passing the mp argument by value here?
Thanks for your help!
The first step is to compile with warnings enabled. Eg if you are using GCC you can use option -Wall -Wextra.
EDIT:
(previous listing of >20 errors removed)
Ok, since you are using Visual Studio, enable warnings like this:
Open the project's Property Pages dialog box.
Select C/C++.
On the General property page, modify the Warning Level to /W4

Resources