I am trying to write a small program in C but I am stuck trying to increment an int.
#include<stdio.h>
#include<string.h>
char * compress(char *input, int size){
char *inputCopy;
char compressedString[100];
snprintf(inputCopy, size, "%s", input);
int i = 0;
int counter;
int j;
while(i < size){
counter = 1;
j = i;
while (inputCopy[j] == inputCopy[j + 1] && j < size){
j++;
printf("same! \n");
counter++; // When this line is commented out it works.
}
if (i != j){
i = j;
}else{
i++;
}
}
return inputCopy;
}
main(){
char test[10] = "aaaaaaasdd";
printf("%s \n", compress(test, 10));
printf("%s", test);
return 0;
}
The counter++ line for some reason is making my program crash.
I know it is probably something simple, but can someone point out to me why this is not working?
You need to check j < size first, and strengthen it to j + 1 < size else you run the risk of an out-of-bounds array access, which is undefined behaviour:
while (j + 1 < size && inputCopy[j] == inputCopy[j + 1]){
(The right hand argument of && is only evaluated if j + 1 < size is 1.)
And where is the memory allocated for inputCopy?
You're not allocating data for snprintf. inputCopy is uninitialized, so it's probably writing over the memory used by counter. Make sure you allocate the necessary memory.
Unrelated to this crash, but you have a potential for invalid reads (inputCopy[j + 1]). Switch j < size to (j + 1) < size and move it to the beginning of the while so you'll short circuit.
valgrind (or Clang's address sanitizer) can help catch both of these issues if you're on a Linux system.
Here you define test as an array of length 10:
char test[10] = "aaaaaaasdd";
Then you pass it to compress with 10 as the size:
printf("%s \n", compress(test, 10));
This conditional will remain true while i is 0 through 9:
while(i < size){
And same for j:
j = i;
And when j is equal to 9, this line will try to access element j + 1, which is 10, of your array, which is out of bounds:
while (inputCopy[j] == inputCopy[j + 1] && j < size){
This will cause undefined behavior. Most likely this is the source of your crash, and the thing with counter is incidental.
EDIT: Aaaaaand you're also not allocating any memory for inputCopy on this line, which will also lead to undefined behavior:
snprintf(inputCopy, size, "%s", input);
It is illegal to write to inputCopy. It points to random memory:
char *inputCopy;
char compressedString[100];
snprintf(inputCopy, size, "%s", input); // !? memory not allocated for the inputCopy
I try to create a program which converts Decimal to Binary and back. My problem is when the fraction part becomes too big in binary, my program crashes. I tried many different approaches to this problem and none of them worked...I dont know why it happens so I have no sollution for it.
This program contains only the issue.
Please help me.
example1: 10 10.5 -> Program works fine
example2:10 10.23 -> Program crashes
Above are examples.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(){
int base;
double number;
scanf("%d %lf",&base,&number);
if(base == 10){
//Integer Part
int n = (int)number;
number = number - (double)n;
int i = 0;
char *binaryfirst;
binaryfirst = malloc(sizeof(char*));
while(n != 0){
binaryfirst[i] = (n % 2) + '0';
n /= 2;
i++;
}
binaryfirst[i] = '\0';
strrev(binaryfirst);
//printf("%lf\n%s\n",number,binaryfirst);
//Fractional part
int j = 0;
char *binarysecond;
binarysecond = malloc(sizeof(char*));
//This is The part where I am lost...
for(j = 0; j < 60; j++){ //60 is the maximum length that it can become
number *= 2;
if(number >= 1.0){
binarysecond[j] = '1';
number = number - 1;
}else if(number == 0){
binarysecond[j] = '0';
break;
}else{
binarysecond[j] = '0';
}
printf("%lf; %c\n",number, binarysecond[j]);
}
printf("%d\n",j);
binarysecond[j] = '\0';
//printf("\n%s\n",binarysecond);
//Memory "Let it go"!!!!
/* for(i = 0; i < sizeof(binaryfirst); i++){
free(binaryfirst[i]*2);
}*/
free(binaryfirst);
/* for(j = 0; j < sizeof(binarysecond); j++){
free(binarysecond[j]);
}*/
free(binarysecond);
}
return 0;
}
This:
binaryfirst = malloc(sizeof(char*));
and
binarysecond = malloc(sizeof(char*));
allocates the size of a pointer, but the loop that writes to it makes it clear that it expects to store at most 60 bytes at that location. This makes no sense at all; C does not magically grow the allocation when you write outsite it, instead you get undefined behavior.
If you're unsure about heap memory allocations, and they're not crucial to the problem you're trying to solve, first do it without any. Just use simple arrays:
char binaryfirst64];
char binarysecond[64];
Every time I find a pretty good solution to a problem at my work, always start coding in C to ruin that feeling... :D
So here I am, noobing with some easy C code and wonder why it's not working o.O
I want to represent a matrix with a 2D array (array of arrays) and fill it from a text file. The code is bad, the code ugly... I'm interested any tip/trick what I can fetch from you, Mr. senior :)
What wrong with my logic? What is under the hood? Am I using the [] operator not as expected? Am I just simply don't know how to iterate through a 2D array? I complie this source on windows with cl, using declaration in for() and god know what else what is not strictly C-like.
Input is a text file containing the size of the matrix and the elements of it separated by white space(s). The syntax of this: file := {n, A | n :-N, A := N^(n*n)}
For example:
3
1 3 2
4 5 2
7 0 1
So here it is... take cover!
#include <stdio.h>
int main(int argc, char **argv) {
Opening the file, no error checking for the minimal code :)
FILE *fp = fopen("mat_mul.test", "r");
Now, allocating the arrays based on the first integer in the file... Is this correct? Are there any better approach for allocating array of arrays?
int n = fgetc(fp) - '0';
int **A = (int**) malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++)
A[i] = (int*) malloc(sizeof(int) * n);
Aaand, here is the magic, the spell what has turned against its master :D
char act;
int i = 0, j = 0;
while (EOF != (act = fgetc(fp)))
if ('0' <= act && '9' >= act)
A[j == n - 1 ? i++ : i][j == n - 1 ? j = 0 : j++] = act - '0';
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("A[%i][%i]=%i\n", i, j, A[i][j]);
}
}
Cleaning without exhaustive!
if (fclose(fp)) {
return 0;
}
You invoke undefined behaviour when you try to do the row and column assignment and advancement at once here:
A[j == n - 1 ? i++ : i][j == n - 1 ? j = 0 : j++] = act - '0';
You assign to j in the second pair of brackets and also access its value in the first pair. (My compiler warns me that the "operation on 'j' may be undefined".) There is a sequence point between the parts of the ternary operatoy, but not between the two index operators [].
Besides the undefined behaviour, the expression is also needlessly complicated in my opinion. Separate assignmemt and advancing the row and columns counter:
if ('0' <= act && '9' >= act) {
A[i][j] = act - '0';
j++;
if (j == n) {
j = 0;
i++;
if (i == n) break; // end outer while
}
}
You should also include <stdlib.h> for the declaration of malloc. (That's also something my compiler tells me when warnings are enabled.)
Alright, so, just for fun, I was working on the sieve of eratosthenes.
It was working fine intially so I sought out to improve its runtime complexity. and now, I on't know why, but I'm gettig a segmentation fault.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* check = malloc(1000000000 * sizeof(int));
long long int i;
for(i = 0;i < 1000000000;i++)
{
check[i] = 0;
}
int j = 0;
for(i = 2;i <= 1000000002;i++)
{
if(check[i] == 0)
{
printf("%lld\n", i);
for(j = 1;j < (1000000001/i);j++)
{
check[j*i] == 1;
}
}
}
return 0;
}
Any help as to why it fails would be appreciated.
Your code has multiple errors, any of which could explain a segfault. First, you have not checked the return value of malloc, which may be NULL, even when you are totally sure it couldn't be.
Second, you are exceeding the bounds of the array you've allocated when you iterate i from 2 to 1000000002. With so many zeros it's hard to eyeball, so here are your figures with separators:
Initial allocation: 1,000,000,000
Range of i: 2 to 1,000,000,002 inclusive
At the end of that loop you are accessing memory past the end of your array.
#include <stdio.h>
#include <stdlib.h>
#if 1
static const size_t N = 1000 * 1000 * 1000;
#else
static const size_t N = 1000;
#endif
Don't use a magic number, define it as a constant. 1000000000 is also hard to read. Your C compiler can do calculation for you before it emits an executable. And you should have started with a small number. If you change #if 1 into #if 0, then the #else clause defining N as 1,000 will take effect.
int main(void)
{
char* check = malloc(N + 3);
When you essentially use check as a boolean array, it doesn't have to be of type int. int occupies 4 bytes whereas char only 1 byte.
if (NULL == check) {
perror("malloc");
abort();
}
malloc silently returns NULL when it failed to find a memory chunk of the specified length. But if you work with 64 bit OS and compiler, I don't think it's likely to fail...
long long int i;
memset(check, 0, sizeof(check[0]) * (N + 3));
memset fills an array with the value of the 2nd parameter (here 0.) The third parameter takes the number of BYTES of the input array, so I used sizeof(check[0]) (this is not necessary for a char array becuase sizeof(char)==1 but I always stick to this practice.)
int j = 0;
for(i = 2;i <= N+2;i++)
{
if(check[i] == 0)
{
printf("%lld\n", i);
for(j = 1;j < ((N+1)/i);j++)
{
check[j*i] = 1;
You wrote check[j*i] == 1 but it was an equality test whose result didn't have any effects.
}
}
}
free(check);
It is a good practice to always free the memory chunk that you allocated with malloc, regardless whether free is necessary or not (in this case no, because your program just exits at the end of sieve calculation.) Perhaps until you become really fluent with C.
return 0;
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm working on a problem where I'm given a sorted array of integers, and I am supposed to take an input from the user, search for the input, and return the first instance of that input (if it exists) and the number of times it appears.
I wrote a program with the following approach: I take an input from the user. I then use binary search to find the value. If it exists, then I store the index as m. After that, I write two while loops. The first loop checks for the number of occurrences of the value to the left and the second does the same, but to the right. For example, the binary search might be looking for 5, and it finds it. However, it lands on the 3rd one, ie. {.....5,5,**5**,5....}. The first while loop will count the two the the left and the second while loop will count the one to the right. Then I'll sum them all up and return the total number of instances. If the the input value does not exist, then I skip the afore-mentioned code and simply return -1.
In the body of the main function, I then check the return value. If it is -1, I tell the user that the value has not been found. If the return value is >=0, then I print the required info.
Anyways, I have written up the C code for the program, but I cannot get it to work properly. I get a seg. fault error, I don't know what I'm doing wrong though. Anyways, any help would be appreciated. I've been pounding my head on this problem for awhile. It's been interesting and hard, and I think I have the right logic; but I cannot get it to work properly. Anyways, here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
/* function prototype */
int get_num_of_ints( const int* arr, size_t r, int N, size_t* f, size_t* count );
int main()
{
int i;
int N; /* input variable */
int arr[]={1,1,2,3,4,4,4,4,5,5,6,7,7,7,7,8,9,9}; /* array of sorted integers */
size_t r = sizeof(arr[i])/sizeof(int); /* right bound */
size_t f; /* first match index */
size_t *fPtr;
fPtr = &f;
size_t count; /* total number of matches */
size_t *countPtr;
countPtr = &count;
printf( "\nPlease input the integer you would like to find.\n" );
scanf( "%d", &N );
int a = get_num_of_ints( arr, r, N, fPtr, countPtr );
if( a == -1)
printf( "%d has not been found.\n", N );
else if(a >= 0){
printf( "The first index is %d.\n", f );
printf( "The total number of values is %d.\n", count );
}
return 0;
}
/* function definition */
int get_num_of_ints( const int* arr, size_t r, int N, size_t* f, size_t* count )
{
int l = 0;
int m;
int w=r;
size_t *fPtr;
size_t *countPtr;
while(l <= r){
m = l +(r - l)/2;
if(arr[m] < N)
l = m+1;
else if(arr[m] > N)
r = m-1;
else if(arr[m]==N)
m=m;
break;
}
if( l > r)
m = -1;
if( m >= 0 ){
int j = m-1;
int L = 0;
while(arr[j] == arr[m] && j >= 0){
L++;
j--;
}
if( j>= 0 && L > 0 )
*fPtr=j;
else
*fPtr=m;
int h = m + 1;
int R = 0;
while( arr[h]==arr[m] && h <= w ){
R++;
h++;
}
*countPtr = (R + L + 1);
return *fPtr;
}
else if( m==-1)
return -1;
}
while(arr[j] == arr[m] && j >= 0)
You should switch the order of the two conditions here, or you'll try to read arr[-1]. Same thing for the second while loop.
Another problem is that r should start at 1 less than the array size, since arr[array_size] is past the end.
Edit:
A serious problem is that you are writing to the uninitialized pointers countPtr and fPtr when you should be writing to *count and *f. This is probably what's causing the segfault. This would have been easy to spot in a debugger.
Use variable names that mean something. You might find the problem immediately.
Run the program in a debugger and step through the code; you should see where things are going wrong pretty quickly. (Hint, what's fPtr used for in get_num_of_ints? There are other bugs too as others have pointed out).
Since you need the number of occurrences, you need to search through each element, right?
Why not simplify things and just do a linear scan? Here's some pseudocode:
function get_num_of_ints(arr, n){
first_index = -1
count = 0
for(i = 0; i < length(arr); i++)
if(x == n){
count++
if(first_index == -1)
first_index = i
}
return count, first_index
}
I don't have a C compiler in the computer I'm sitting now, so I can't test it, but I see that in the first while-loop of your function you're saying:
else if(arr[m]==N)
m=m;
break;
The break statement is outside the if in this case, so the while loop will execute only once each time.
I don't know if this causes the error though.
The segmentation fault comes from get_num_of_ints() in lines 74, 77, and 87.
if( j>= 0 && L > 0 )
*fPtr=j;
else
*fPtr=m;
...
*countPtr = (R + L + 1);
You have not assigned a memory address to the pointers, and thus you are using an arbitrary memory location in these lines.
It doesn't seem like there's any real reason to be using a pointer for these variables anyway. Try changing them from pointers to size_t to just variables of type size_t.
size_t fPtr;
size_t countPtr;
In get_num_of_ints() function you are using pointer fptr without allocating memory to it.
Thanks to everybody's comments, I was able to find all the bugs in my program, and use the gdb debugger too. Anyways, I no longer have my seg. fault errors when I run the program; however, I have some sort of logic problem becauase when I prompt the user for an input,and say the user types 4, then the outputs for # of occurence and location of first occurrence are garbage values.
I get:
Please input the integer you would like to find.
4
The first index is -1075300456.
The total number of values is 12169204.
This revolves around the issue I had earlier with the last two parameters in my function. At the bottom, in the function definition, I want count to be the total number of occurrences found in the list.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
/* function prototype */
int get_num_of_ints( const int* arr, size_t r, int N, size_t f, size_t count );
int main()
{
int i;
int N; /* input variable */
int arr[]={1,1,2,3,4,4,4,4,5,5,6,7,7,7,7,8,9,9}; /* array of sorted integers */
size_t r = sizeof(arr)/sizeof(arr[0]) - 1; /* right bound */
size_t f; /* first match index */
size_t count; /* total number of matches */
printf( "\nPlease input the integer you would like to find.\n" );
scanf( "%d", &N );
int a = get_num_of_ints( arr, r, N, f, count );
if( a == -1)
printf( "%d has not been found.\n", N );
else if(a >= 0){
printf( "The first index is %d.\n", f );
printf( "The total number of values is %d.\n", count );
}
return 0;
}
/* function definition */
int get_num_of_ints( const int* arr, size_t r, int N, size_t f, size_t count )
{
int l = 0;
int m;
int w=r;
while(l <= r){
m = l +(r - l)/2;
if(arr[m] < N)
l = m+1;
else if(arr[m] > N)
r = m-1;
else if(arr[m]==N){
m=m;
break;
}
}
if( l > r)
m = -1;
if( m >= 0 ){
int j = m-1;
int L = 0;
while( j >= 0 && arr[j] == arr[m] ){
L++;
j--;
}
if( j>= 0 && L > 0 )
f=j;
else
f=m;
int h = m + 1;
int R = 0;
while( arr[h]==arr[m] && h <= w ){
R++;
h++;
}
count = (R + L + 1);
return f;
}
else if( m==-1)
return -1;
}
As everyone pointed out countPtr and fPtr needs to be allocated with memory
size_t *fPtr = malloc(sizeof(size_t));
Make sure you intialize "i" with some value before using it
Compile the program (if you are in Linux) with # gcc -g -Wall <your c file name> -o arraysort
Start the debugger, step through the code to find out valeues, I found several funny values for r, arr[m],
#gdb ./arraysort
b
run
[inspect variables here]
HTH