I was given a file with several recipes denoted at the beginning by 0. Each recipe is followed by it's ingredients denoted at the beginning by 1 as shown below :
char *rawRecipes[]={
"0Broccoli Coleslaw",
"1olive oil",
"1white vinegar",
"1white sugar",
"1package chicken flavored ramen noodles",
"1broccoli",
"1carrots",
"1green onions",
"1sunflower seeds",
"0Creamy Broccoli Salad",
"1broccoli",
"1red onion",
I'm trying to alphabetically sort the ingredients in a list, but I'm getting segmentation fault. I would greatly appreciate your help on this. Here is what I've done:
int main(void)
{
int input;
printf("\n");
printf("\n");
printf("Enter a command by number\n");
printf("4. List All Ingredients in alphabetical order\n");
printf("Give input: ");
scanf("%d", &input);
if (input == 4) // List All Ingredients in alphabetical order
{
int i = 0,k;
char alphabet[1000] ;
while(strcmp(rawRecipes[i], "") !=0)
{
if(rawRecipes[i][0] == 1 && rawRecipes[i+1][0] == 1)
{
char temp;
for(k=0; k<250; k++)
{
alphabet[k] = rawRecipes[i];
alphabet[k + 1] = rawRecipes[i + 1];
}
if(strcmp(alphabet[i], alphabet[i + 1] > 0))
{
temp = alphabet[i];
strcpy(alphabet[i], alphabet[i + 1]);
strcpy(alphabet[i + 1], temp);
}
}
i++;
}
int m;
for(m=0; m < 250; m++)
{
printf("%d: %c", m, alphabet[m]);
}
}
return 0;
}
In this code:
int i,k;
char alphabet[1000] ;
while(strcmp(rawRecipes[i], "") !=0)
What do you expect the value of i to be?
That value is undefined, and could be 0, -10000, or 10000000. Some of the possible values will cause immediate crash right on the first iteration through the loop, while trying to construct an argument to strcmp (due to i being out of range for access to rawRecipes).
You probably want: int i = 0, k;.
There are other bugs as well.
You should really learn how to use a debugger, and how to debug small programs.
And before debugging, you should turn on compiler warnings, and fix all of the bugs compiler will tell you about.
Here is one from GCC:
t.c:41:37: warning: assignment to ‘char’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]
41 | alphabet[k] = rawRecipes[i];
Related
I'm trying to create a function that will delete an item from an array of structs. When I enter a number (scanf("%d", num)), I get a pop-up saying I have an assertion failure and to abort the program. There was a warning on the indicated line below, but it didn't stop the program from compiling. When the program crashes the error appears on the same line:
void delete_stud(Student* s, int lsize)
{
int num = 0;
printf("What number student in the list would you like to delete?\nStudent number: ");
scanf("%d", num);
// This line ^^^
if (num <= lsize) {
for (int i = num; i <= lsize; i++) {
s[i - 1] = s[i];
}
lsize--;
}
else {
printf("Invalid value entered\n");
exit(0);
}
}
I call the function with:
delete_stud(class_list, lsize);
Any help would be greatly appreciated.
scanf("%d", &num);
Note the ampersand.
I got a little assignment to do with C, but I can't seam to fill up an array that I allocated memory to. The code is like so..
#include<stdio.h>
#include<stdlib.h>
int main(){
int *x, *y, n, m, i;
printf("Enter lenght of arrays x and y (separated by space): ");
scanf("%d%d", &n, &m); fflush(stdin);
if (x = (int*)malloc(sizeof(int) * n) == NULL){
fprintf(stderr, "Error!\n");
exit(1);
}
if (y = (int*)malloc(sizeof(int) * m) == NULL){
fprintf(stderr, "Error!\n");
exit(1);
}
printf("Enter %d values for X array (separated by space) ", n);
for (i = 0; i < n; i++)
scanf("%d", x + i);
fflush(stdin);
printf("Enter %d values for Y array (separated by space): ", m);
for (i = 0; i < m; i++)
scanf("%d", y + i);
} //the two for's were originally in a function, I tried using the code like this as well
return 0;
}
I also tried running scanf("%d", x[i]); but nothing works. Every time I hit Enter after typing in the array for X the program crashes. By the way, originally no fflush(stdin) was there originally, I added them because I thought that the input took \0 as one of the values and that created errors.
Thank you for reading! :)
The code has a bunch of misplaced braces and parentheses, especially in the if statements. You have to wrap the assignments in parenthesis before doing the comparison, else they're misassigned. Try this, it compiled and worked for me:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *x, *y, n, m, i;
printf("Enter lenght of arrays x and y (separated by space): ");
scanf("%d%d", &n, &m);
if ((x = (int*)malloc(sizeof(int) * n)) == NULL){
fprintf(stderr, "Error!\n");
exit(1);
}
if ((y = (int*)malloc(sizeof(int) * m)) == NULL){
fprintf(stderr, "Error!\n");
exit(1);
}
printf("Enter %d values for X array (separated by space) ", n);
for (i = 0; i < n; i++)
scanf("%d", x + i);
printf("Enter %d values for Y array (separated by space): ", m);
for (i = 0; i < m; i++)
scanf("%d", y + i);
//the two for's were originally in a function, I tried using the code like this as well
return 0;
}
And like everyone else says, don't use fflush(stdin)
The use of fflush(stdin) is probably causing the crash, since it's undefined behavior in standard C.
Take a look at this answer what is the use of fflush(stdin) in c programming
I tried to compile the programm with Visual Studio 2013 and got 2 errors at the lines with malloc:
error C2440: '=' : cannot convert from 'bool' to 'int *'
After i fixed both lines by
if ((x = (int*)malloc(sizeof(int) * n)) == NULL){
or
if (x = (int*)malloc(sizeof(int) * n)){
the program runs without any problems.
I don't understand why you could compile the code, but it does the following:
compare (int*)malloc(sizeof(int) * n) == NULL result is false
and now set y = false and y does not point to the allocated array.
This is homework, but the as the tag is deprecated i'm pointing this out here...
I'm working on an assignment using cuda that does a strightforward match of a pattern in a string. The text file contains 1,000,000 chars, (all the same char, but the last is different) and a pattern of size 100 (again all the same char, with the final one different), so the pattern should be found at position 999,000 of the text.
I am trying to get this to work with 10 threads, and so I am setting the starting points of the algorithm accordingly.
blocksize is set to 10,000 and the startPoint variable is the thread id (0-9).
int i,j,k,lastI;
i=startPoint*blockSize;
j=0;
k=startPoint*blockSize; //may be -1...
int end;
end = ((startPoint+1) * blockSize) - patternLength; //may be -1
//*testchar = dev_textData[((startPoint+1) * blockSize) -1];
*testchar = dev_pattData[patternLength-1];
*testchar = dev_textData[textLength-1];
//*testchar = dev_textData[i+blockSize-1];
//*result = end;
//return;
while (i<=end && j<patternLength)
{
if (dev_textData[k] == dev_pattData[j]) //going out of bounds at the j i think...
{
k++;
j++;
}
else
{
i++;
k=i;
j=0;
}
}
if (j == patternLength)
{
*result = i;
*testchar = 'f';
}
else
{
*result = -1;
Firstly the program here seems to error, with the cuda error 30, unknown error (I think this is a segfault perhaps??), but when I change
if (dev_textData[k] == dev_pattData[j])
to
if (dev_textData[k] == dev_pattData[j-1])
The error disappears, however because i'm matching on the last char the algo does not work correctly.
I can't seem to figure out why the j-1 makes a difference here because of the while loop boundary.
Any help / advice / pointers would be greatly appreciated.
Thanks
First, let's do the math. If you have 1,000,000 chars and the pattern length is 100, then the pattern should be found at 999,900. If you split the work between 10 threads, then each thread should be given 100,000 bytes. The reason I'm giving you a hard time is that I have to wonder whether the pattern length actually matches the pattern. In other words, does the pattern actually have 100 bytes in it, or does it only have 99 bytes?
One way to debug problems like this is to
take your original code
place it in a test environment with a tiny dataset
strip out all of the distracting nonsense
add some printf's for debugging
Here's what the code looks like after doing that
int i,j,k,end;
char textData[10] = "aaaaaaaaab";
char pattData[5] = "aaaab";
int blockSize = 10;
int patternLength = 5;
int startPoint = 0;
i=startPoint*blockSize;
j=0;
k=startPoint*blockSize;
end = ((startPoint+1) * blockSize) - patternLength;
while (i<=end && j<patternLength)
{
printf( "i=%d j=%d k=%d -- ", i, j, k );
if (textData[k] == pattData[j])
{
k++;
j++;
printf( "match newi=%d newj=%d newk=%d\n", i, j, k );
}
else
{
i++;
k=i;
j=0;
printf( "fail newi=%d newj=%d newk=%d\n", i, j, k );
}
}
printf( "end-of-loop i=%d j=%d k=%d\n", i, j, k );
if (j == patternLength)
{
printf( "pattern found at %d\n", i );
}
else
{
printf( "not found\n" );
}
And guess what ... the code works!!! So the problem has nothing to do with the core algorithm, but is somewhere else in your code.
Actually i am trying to solve SPOJ Problem:
[SPOJ] http://www.spoj.com/problems/SQRBR/ . I came up with recurence to solve it but i am not getting how to do memoisation. Any suggestion on how to memoisation for given problem will be helpful. my code is giving correct answer , but it is giving TLE in spoj Here my code :
#include <iostream>
#include <cstdio>
using namespace std;
void balancedParen(int n, int open, int position, int close, char str[], string s, long long int &counter) {
if(close == n) {
str[pos] = '\0';
printf("%s\n", str);
counter++;
return;
}
if(s[position] == '(' ) {
if(open <= n-1) {
str[position] = '(';
balancedParen(n, open+1, position+1, close, str, s, counter);
}
} else {
if(open < n) {
str[position] = '(';
balancedParen(n, open+1, position+1, close, str, s, counter);
}
if(open > close) {
str[position] = ')';
balancedParen(n, open, position+1, close+1, str, s, counter);
}
}
return ;
}
int main() {
int a[100], n, k, i;
long long counter = 0;
int testCases;
scanf("%d", &testCases);
while(testCases--) {
scanf("%d", &n);
scanf("%d", &k);
char str[100];
string s = "..........................................................................";
for(i = 0; i < k; i++) {
scanf("%d", &a[i]);
s[a[i]-1] = '(';
}
balancedParen(n, 0, 0, 0, str, s, counter);
printf("%lld\n", counter);
counter = 0;
}
return 0;
}
I can think of one relatively simple and possibly significant optimization.
First, instead of making the "counter" a reference, make it the return value of the function. Hear me out for a bit here.
Now say the positions you're given are "1, 7, 15". Instead of recursively going "1, 2, 3, 4, 5, 6, 7", you can be a little tricky and go to 7 in one step.
You just need to count the number of permutations which can be used to go between 1 and 7, for every possible number of opening parens (in this case, 3, 4, 5 and 6)
For example, how many ways exist to have 3 opening parens between 1 and 7?
[[[]]]
[[][]]
[][][]
[[]][]
[][[]]
5 permutations (unless I missed one). So you can add 5*balancedParen(n, open+3, position+6, close+3, str, s, counter) to your result. And do a similar thing for 4, 5, and 6 opening parens.
Of course you'd need to write another function (recursive approach seems simplest) to find that number "5". But the advantage is that the total number of function calls is now (calls to get from 1 to 7) + (calls to get from 7 to 15), rather than (calls to get from 1 to 7) * (calls to get from 7 to 15).
Here is some code which should work using the algorithm I described:
int countPermutations(int unclosed, int length, int toOpen)
{
if (toOpen > length) // impossible to open this many, not enough length
return 0;
int toClose = length-toOpen;
if (toClose - toOpen > unclosed)
return 0; // No possibilities; not enough open parens to fill the length
if (toOpen == 0 || toOpen == length)
return 1; // Only one possibility now
int ret = 0;
if (toOpen > 0) // Count permutations if we opened a paren here
ret += countPermutations(unclosed+1, length-1, toOpen-1);
if (unclosed > 0) // Count permutations if we closed a paren here
ret += countPermutations(unclosed-1, length-1, toOpen);
return ret;
}
int countNLengthSolutions(int n, int unclosed, int position, int *positions, int remainingPositions)
{
if (n % 2 != 0)
return 0; // must be a length divisible by 2
if (position > n)
return 0;
if (n-position < unclosed)
return 0; // too many open parens, no way to complete within length
if (remainingPositions == 0)
{
// Too many open parens to close by the time we get to length N?
if ((n - position) < unclosed)
return 0;
else // Say we have 4 open and a length of 10 to fill; we want (10-4)/2 = 3 more open parens.
return countPermutations(unclosed, n-position, (n-position - unclosed)/2);
}
else
{
int ret = 0;
int toFill = *positions - position - 1;
for (int openParens = 0; openParens <= toFill; openParens++)
{
int permutations = countPermutations(unclosed, toFill, openParens);
if (permutations > 0)
ret += permutations*countNLengthSolutions(n, unclosed+(2*openParens-toFill)+1, position+toFill+1, positions+1, remainingPositions-1);
}
return ret;
}
}
I may have a bug somewhere, I didn't really spend the time to check, but I verified it works for all the sample input.
I have looking all over forums to try and understand this issue. The reasons I cannot fully understand the issue and why I cannot find a solution is because I am fairly new with C++ and I do not understand the error message.
This is my code in C++ that finds the number of possibilities from permutation or combination formulas. Every I try and compile and run, I get messages that say:
First-chance exception at 0x6a8613af (msvcr100d.dll) in
Combinations_Permutations.exe: 0xC0000005: Access violation reading
location 0x00000005. Unhandled exception at 0x6a8613af (msvcr100d.dll)
in Combinations_Permutations.exe: 0xC0000005: Access violation reading
location 0x00000005.
I've learned on many other forums that the "access violation reading location 0x00..." could definitely indicate null pointer. But I cannot see where I encounter such a null issue. Maybe my variables are being accessed globally, where they are not YET initialized?
Here is my code, I have been at it for a while... like I said I'm fairly new. So please inform me of my mistake(s). Thank you.
My code:
#include <iostream>
#include "conio.h";
using namespace std;
int run_combination(int n, int r);
int run_permutation(int n, int r);
int solve_factorial(int f);
int f_value = 1; //factorial value used recursively
int n_input, r_input;
char choice;
char order;
void main(){
//if user types choice as 'q', while loop ends
while(choice != 'q'){
printf("How many values? (1-9) \n");
printf("User: ");
cin >> n_input;//user input for variable n
printf("n_input: %i", n_input);
printf("\nHow many will be chosen at a time out of those values? (1-9)\n");
printf("User: ");
cin >> r_input; //user input for variable r
printf("\nDoes order matter? (y/n)\n");
printf("User: ");
cin >> order; //'y' if order is taken into consideration(permutation)
//'n' if order it NOT taken into consideration(combination)
int solution = 0; //temporary variable that represents the solution after running
//n and r through the permutation or combination formula
//if user input values for n and r are in between 1 and 9, then run
//combination or permutation
if (n_input <= 9 && n_input >= 1 && r_input <= 9 && r_input >= 1){
if (order == 'y')
solution = run_permutation(n_input, r_input);
else if (order == 'n')
solution = run_combination(n_input, r_input);
else
printf("\nError. Please type 'y' or 'n' to determine if order matters.\n");
//if n < r, run_permutation or run_combination returns 0
if (solution == 0){
printf("Error! You can't choose %i values at a time if there \n",
"are only %i total values. Type in new values next loop \n.", r_input, n_input);
}
else
printf("Number of possibilities: %s", solution);
}
else{ //else error message if numbers are out of range...
printf("Next loop, type in values that range from 1 to 9.\n");
}
//option 'q' to quit out of loop
printf("Type 'q' to quit or enter any key to continue.\n");
printf("User: ");
cin >> choice;
}
_getch();
}
/*
Returns solved combination of parameters n and r
Takes the form: n! / r!(n-r)!
*/
int run_combination(int n, int r){
if (n < r) //solution is impossible because you can't choose r amounnt at a time if r is greater than n
return 0;
int n_fac = solve_factorial(n); //n!
int r_fac = solve_factorial(r); //r!
int nMinusr_fac = solve_factorial(n-r); //(n-r)!
int solve = ((n_fac) / ((r_fac)*(nMinusr_fac))); // plugging in solved factorials into the combination formula
return solve;
}
int run_permutation(int n, int r){
if (n < r)
return 0;
int n_fac = solve_factorial(n);
int nMinusr_fac = solve_factorial(n-r);
int solve = ((n_fac) / (nMinusr_fac)); //plugging in factorials into permutation formula
return solve;
}
int solve_factorial(int f){
if (f-1==0 || f == 0){ //if parameter f is 1 or 0, return 1
int temp = f_value;
f_value = 1; //reset f_value so that f_value remains 1 at the start of every new factorial
return temp;
}
else{ //else multiply f_value by f-1
f_value *= f;
return solve_factorial(f-1);
}
}
This is a mistake:
printf("Number of possibilities: %s", solution);
solution is an int, not a null terminated string: use %d.
Using std::cout which is typesafe, instead of printf(), would have prevented this error:
std::cout << "Number of possibilities: " << solution;
The problematic line is:
printf("Number of possibilities: %s", solution);
You're telling printf that solution is a char*, and so it tries to dereference (char*)solution to print the contents of the "C-string" (presumably when solution has the value 5 in the case of your particular error message).
Change %s to %d, or use std::cout instead of printf to gain type-safety and avoid this sort of issue in the first place.