Converting a string of digits to an integer, storing the result - c

Sorry for the confusing question, but what I'm trying to do is store an array in a variable.
I want to store the numbers in *value so that instead of int value: -12118433669 it will be int value: 123456789.
OUTPUT
123456789
array: '123456789' int value: -1218433669
0001234
array: '0001234' int value: -1218433669
5
array: 'abc5xyz' int value: -1218433669
array: '' int value: -1218433669
987654321
array: '987654321' int value: -1218433669
SOURCE
#include <stdio.h>
MyFNatoi(char *numArray, int *value) {
int i;
for (i = 0; i < 10; i++) {
if (numArray[i] > 47 && numArray[i] < 58) {
printf("%c", numArray[i] - 0);
}
}
}
int main() {
char numbers[5][10] = { "123456789", "0001234", "abc5xyz", "", "987654321" };
int i, value;
for(i = 0; i < 5; i++) {
MyFNatoi(numbers[i], &value);
printf("\narray: '%s' int value: %d\n", numbers[i], value);
}
return 0;
}

I propose this function:
void MyFNatoi(const char *str, int *value)
{
if (value == NULL)
return;
*value = 0;
if (str != NULL)
{
int negative = 0;
if (*str == '-')
{
negative = 1;
str++;
}
while (*str && isdigit(*str))
{
*value = (*value * 10) + (*str++ - '0');
}
if (negative)
*value *= -1;
}
}
It handles negative numbers, and only checks leading digits (so wont make a number out of "abc123def456" for example).

#define Zero '0'
#define Nine '9'
void MyFNatoi(char *numArray, int *value) {
int i;
*value = 0;
for (i = 0; i < 10 && numArray[i] != 0; i++) {
if (numArray[i] >= Zero && numArray[i] <= Nine) {
*value = *value * 10 + (numArray[i] - Zero);
}
}
}

My Version:
void MyFNatoi(char *numArray, int *value)
{
for (*value = 0; *numArray != '\0'; ++numArray) {
if (0x30 <= *numArray && *numArray <= 0x39) {
*value = 10* *value + *numArray - 0x30;
}
}
}

Related

My problem with the size of the number in the My_Mastermind minigame

can you help me with the size of the digits, for example, when I enter 01234, then everything works as it should, but it shouldn’t, the limit of digits should be within four.When I enter some four-digit number, everything works as it should work. But when some five-digit, six-digit or even more, then everything works as if it should be, but it should not work like that. And when I enter numbers that are less than four-digit, for example 123 , then it gives an error and it's good. But when I enter numbers that are more than four digits, it does not give an error and works as if it should be so.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
typedef struct s_mastermind {
int my_attempt;
char* my_code;
} my_mastermind;
my_mastermind* settings_function(my_mastermind* mastermind, int argc, char** argv);
int checking_for_correctness_num(char* _string);
int wrong_input(int progress,char* num_code);
my_mastermind* my_function();
int check_function(char* string);
char* input_function();
int mis_placed_pieces(char* bit, char* num_code);
int well_placed_pieces(char* bit, char* num_code);
int code_checker(char* bit, char* num_code);
char* size_of_function(char* strye);
char* my_strcpy(char* num1, char* num2) {
for(int i = 0; num2[i] != 0; i++) {
num1[i] = num2[i];
}
return num1;
}
int my_strlen(char* num1) {
return (*num1) ? my_strlen(++num1) + 1 : 0;
}
my_mastermind* my_function() {
my_mastermind* num = malloc(sizeof(my_mastermind));
num->my_code = malloc(5);
num->my_code[4] = '\0';
my_strcpy(num->my_code, "");
num->my_attempt = 10;
return num;
}
my_mastermind* settings_function(my_mastermind* mastermind, int argc, char** argv) {
char* bit;
for(int i = 0; i < argc;) {
if (my_strlen(argv[i]) == 2 && argv[i][0] == '-') {
if(argv[i][1] == 'c') {
char* num_code = argv[i + 1];
if(wrong_input(argc,num_code) != 0) {
break;
}
my_strcpy(mastermind->my_code, num_code);
}else if(argv[i][1] == 't') {
if(checking_for_correctness_num(argv[i + 1]) == 0) {
mastermind->my_attempt = check_function(argv[i + 1]);
}
} else {
printf("WRONG FLAG RESTART THE GAME!!!\n");
}
}
i += 1;
}
return mastermind;
}
int wrong_input(int progress,char* num_code) {
// if(my_strlen(num_code) != 4) {
// printf("Code bigger than 4\n");
// }
if(checking_for_correctness_num(num_code) == 1) {
printf("Wrong input!\n> ");
fflush(stdout);
char* code = input_function();
char* variable = size_of_function(code);
free(code);
int results = 1;
if(wrong_input(progress,variable) == 0) {
results = code_checker(num_code, variable);
}
free(variable);
return results;
}
return 0;
}
int checking_for_correctness_num(char* _string) {
for(int i = 0; _string[i] != '\0'; i++) {
if(!(_string[i] >= '0' && _string[i] <= '9')) {
return 1;
}
}
return 0;
}
int check_function(char* string) {
int check_num = 0;
for(int i = 0; string[i] != '\0'; i++) {
check_num = check_num * 10 + (string[i] - '0');
}
return check_num;
}
char* input_function() {
char* getting = malloc(101);
getting[100] = '\0';
read(0, getting, 100);
fflush(stdout);
return getting;
}
int game_progress(int progress, char* bit) {
printf("Round: %d\n> ", progress);
fflush(stdout);
char* code = input_function();
char* variable = size_of_function(code);
free(code);
int results = 1;
if(wrong_input(progress,variable) == 0) {
results = code_checker(bit, variable);
}
free(variable);
return results;
}
void game_action(my_mastermind* mastermind) {
int current_try = 0;
for (;current_try < mastermind->my_attempt;) {
int results = game_progress(current_try, mastermind->my_code);
current_try += 1;
if(results == 0) {
printf("Congratz! You did it!\n");
break;
}
}
}
int code_checker(char* bit, char* num_code) {
int good_w = well_placed_pieces(bit, num_code);
int not_good_m = mis_placed_pieces(bit, num_code);
if(good_w == 3 || good_w == 2 || good_w == 1 || not_good_m == 3 || not_good_m == 2 || not_good_m == 1){
printf("Well placed pieces: %d\nMisplaced pieces: %d\n---\n", good_w,not_good_m);
}
if(good_w == 4) {
return 0;
} else {
return 1;
}
}
int well_placed_pieces(char* bit, char* num_code) {
int number = 0;
for(int i = 0; i < 4; i++) {
if (bit[i] == num_code[i]) {
number += 1;
}
}
return number;
}
int mis_placed_pieces(char* bit, char* num_code) {
int number = 0;
int i = 0;
int j = 0;
while(i < 4) {
i++;
if (bit[i] == num_code[i]) {
number += 1;
}
}
return number;
}
char* size_of_function(char* strye) {
char* new_string = malloc(5);
new_string[4] = '\0';
for(int i = 0; i < 4;i++){
new_string[i] = strye[i];
}
return new_string;
}
int main(int argc, char** argv) {
printf("Will you find the secret code?\n---\n");
my_mastermind* mastermind = my_function();
settings_function(mastermind, argc, argv);
game_action(mastermind);
free(mastermind);
return 0;
}
The problem is that you size_of_function assumes the input string is exactly 4 character long, not counting the '\0'. You should either check if the input string and return a error via a NULL pointer, or fully copy the string and check later.
Returning a NULL pointer require the least modification. You can do it by checking the input string size first :
char* size_of_function(char* strye) {
if(my_strlen(strye) != 4)
return NULL;
char* new_string = malloc(5);
new_string[4] = '\0';
for(int i = 0; i < 4;i++){
new_string[i] = strye[i];
}
if (strye[4] == '\r' || strye[4] == '\n' || strye[4] == '\0')
return new_string;
free(new_string);
return NULL;
}
Then, in wrong_input(), check if num_code is NULL :
int wrong_input(int progress,char* num_code) {
if(num_code == NULL || checking_for_correctness_num(num_code) == 1) {
printf("Wrong input!\n> ");
fflush(stdout);
char* code = input_function();
char* variable = size_of_function(code);
free(code);
int results = 1;
if(wrong_input(progress,variable) == 0) {
results = code_checker(num_code, variable);
}
free(variable);
return results;
}
return 0;
}
It is critical to check if num_code is NULL before calling checking_for_correctness_num(). In C the || operator evaluates the left operand first and skip the second operand evaluation if the first one is true. This way we can ensure that we never pass a NULL pointer to checking_for_correctness_num().
wrong_input() is called recursively and allocates memory without freeing it before calling itself. This can eat up memory fast and is generality considered to be bad practice.
Also, you've implemented my_strlen() as a recursive function, which isn't necessary. Using a loop is better :
int my_strlen(char* num1) {
int index = 0;
while(num1[index++]); //Note that 'index' is post-incremented
return index - 1; //Subtract one to account for the last post increment
}

Why do I get an error when I insert something like ';' or '&' in a Plindrome program?

Why do I get an error when I insert something like ';' or '&' in a Palindrome program?
I'd like to create a Palindrome program that automatically excludes special symbols.
eg:
mad!am -> The Palindrome is correct.
But it doesn't work. It only works when I put madam, but when I put mad!am, it gives an error.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX_STACK_SIZE 100
typedef char element;
typedef struct {
element data[MAX_STACK_SIZE];
int top;
} StackType;
void init_stack(StackType* s)
{
s->top = -1;
}
int is_empty(StackType* s)
{
return (s->top == -1);
}
int is_full(StackType* s)
{
return (s->top == (MAX_STACK_SIZE - 1));
}
void push(StackType* s, element item)
{
if (is_full(s)) {
fprintf(stderr, "error\n");
return;
}
else s->data[++(s->top)] = item;
}
element pop(StackType* s)
{
if (is_empty(s)) {
fprintf(stderr, "error\n");
exit(1);
}
else return s->data[(s->top)--];
}
element peek(StackType* s)
{
if (is_empty(s)) {
fprintf(stderr, "error\n");
exit(1);
}
else return s->data[s->top];
}
int main(void)
{
StackType s, a, k;
init_stack(&s);
init_stack(&a);
init_stack(&k);
int i=0;
char input[MAX_STACK_SIZE];
printf("문자열을 입력하세요: ");
scanf("%s", input);
int length = strlen(input);
for (int i = 0; i < length; i++) {
if ('a' <= input[i] && input[i] <= 'z') {
push(&s, input[i]);
push(&a, input[i]);
}
else if ('A' <= input[i] && input[i] <= 'Z') {
push(&s, input[i] - ('A' - 'a'));
push(&a, input[i] - ('A' - 'a'));
}
}
for (int i = 0; i < length; i++)
{
push(&k, pop(&s));
}
while (k.data[MAX_STACK_SIZE]!=NULL) {
if (peek(&a) != peek(&k))
{
printf("not palindrome \n");
break;
return 0;
}
pop(&k);
pop(&a);
printf("palindrome ok!\n");
}
return 0;
}
Avoid constructs like if ('a' <= input[i] && input[i] <= 'z'). That's just makes a mess. In your case, just use isalpha().
But the problem lies in the for loop after you have read all the characters. Since you're skipping characters you cannot use length again. Do these changes:
int length = strlen(input);
int no_letters=0;
for (int i = 0; i < length; i++) {
if (isalpha(input[i])) {
push(&s, input[i]);
push(&a, input[i]);
no_letters++;
}
}
for (int i = 0; i < no_letters; i++)
{
push(&k, pop(&s));
}
There was a small bug with length.. You should ignore counting string length for those element which should not be counted.. Here I have corrected the code with comment , compiled and run.. It is working correct now...
Please try below code... I have added comment what I added..
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX_STACK_SIZE 100
typedef char element;
typedef struct {
element data[MAX_STACK_SIZE];
int top;
} StackType;
void init_stack(StackType* s)
{
s->top = -1;
}
int is_empty(StackType* s)
{
return (s->top == -1);
}
int is_full(StackType* s)
{
return (s->top == (MAX_STACK_SIZE - 1));
}
void push(StackType* s, element item)
{
if (is_full(s)) {
fprintf(stderr, "error\n");
return;
}
else s->data[++(s->top)] = item;
}
element pop(StackType* s)
{
if (is_empty(s)) {
fprintf(stderr, "error\n");
exit(1);
}
else return s->data[(s->top)--];
}
element peek(StackType* s)
{
if (is_empty(s)) {
fprintf(stderr, "error\n");
exit(1);
}
else return s->data[s->top];
}
int main(void)
{
StackType s, a, k;
init_stack(&s);
init_stack(&a);
init_stack(&k);
int i=0;
char input[MAX_STACK_SIZE];
printf("문자열을 입력하세요: ");
scanf("%s", input);
int length = strlen(input);
int len=0; // added
for (int i = 0; i < length; i++) {
if ('a' <= input[i] && input[i] <= 'z') {
push(&s, input[i]);
push(&a, input[i]);
len++; //counting length for valid characters
}
else if ('A' <= input[i] && input[i] <= 'Z') {
push(&s, input[i] - ('A' - 'a'));
push(&a, input[i] - ('A' - 'a'));
len++; //counting length for valid characters only
}
}
for (int i = 0; i < len; i++)
{
push(&k, pop(&s));
}
while (k.data[MAX_STACK_SIZE]!=NULL) {
if (peek(&a) != peek(&k))
{
printf("not palindrome \n");
break;
return 0;
}
pop(&k);
pop(&a);
printf("palindrome ok!\n");
}
return 0;
}

word frequency of string counter is sometimes wrong

I hope you can help me I worked on this code. The code works like this
user inputs a string for example "hey john, how are you john?
the program erases signs like "'?' , ',' '!' " etc.
the program writes a string after erasing the signs : "hey john how are you john?"
and the code outputs the frequency of each word:
hey : 1
john: 2
how : 1
are : 1
you : 1
but my code counts sometimes wrong. For example when I type "bye bye bye hello hello hello"
the output is :
bye : 3
hello : 1
My code does the john example right, but the bye bye... example wrong.
How do I have to change my code? Thank you
#include <stdio.h>
#include <string.h>
char words[80][80];
void clear_string(char *text);
int extract_and_count(char *source, int *count);
void clearArray(char array[]);
int indexInWords(char string[]);
void print(int countOfWords, int count[]);
int equals(char *string1, char *string2);
int main() {
char string[80];
int count[80];
printf("please enter your text: ");
scanf("%[^\n]s", string);
clear_string(string);
printf("%s\n", string);
int countOfWords = extract_and_count(string, count);
print(countOfWords, count);
return 0;
}
void clear_string(char *text){
int i = 0;
for(;i < strlen(text);++i){
if( text[i] == '.' || text[i] == ',' || text[i] == '!' || text[i] == '?'){
int k = i + 1;
for(; k < strlen(text);++k){
text[k-1] = text[k];
}
k = strlen(text) - 1;
text[k] = ' ';
}
}
}
int extract_and_count(char *source, int *count){
int wordCounter = 0;
char string[80];
int i = 0, k = 0;
clearArray(string);
for(; i < strlen(source);++i, ++k){
if(source[i] != ' '){
string[k] = source[i];
}else{
if(string[0] == '\0'){
break;
}
int index = indexInWords(string);
if(index == -1){
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
}else{
count[index] += 1;
}
clearArray(string);
k = -1;
}
}
return wordCounter;
}
void clearArray(char array[]){
memset(array,0,strlen(array));
//array[0] = '\0';
}
int indexInWords(char string[]){
int i = 0;
for(;i < 80;++i){
if(equals(words[i], string) == 0){
return i;
}
}
return -1;
}
void print(int countOfWords, int count[]){
for(int i = 0;i < countOfWords; ++i){
printf("%s : %d\n",words[i], count[i]);
}
}
int equals(char string1[], char string2[]){
return strcmp(string1, string2);
}
The most significant problem I found was in extract_and_count() -- it doesn't count the last word as it only counts words followed by space. The bandaid is to check if string has anything in it after the loop, and if so, process it. Below is my rework for that fix and general style:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
void clear_string(char *text);
int extract_and_count(char *source, int count[]);
void clearArray(char array[]);
int indexInWords(char string[]);
void print(int countOfWords, int count[]);
bool equals(char *string1, char *string2);
#define BUFFER_SIZE (512)
#define MAX_WORD_COUNT (80)
#define MAX_WORD_SIZE (64)
char words[MAX_WORD_COUNT][MAX_WORD_SIZE];
int main() {
char string[BUFFER_SIZE];
int count[MAX_WORD_COUNT];
printf("Please enter your text: ");
while (fgets(string, BUFFER_SIZE, stdin) == NULL) {
printf("Please (re)enter your text: ");
}
clear_string(string);
int countOfWords = extract_and_count(string, count);
print(countOfWords, count);
return 0;
}
void clear_string(char *text) {
for (int i = 0; i < strlen(text); i++) {
if (text[i] == '.' || text[i] == ',' || text[i] == '!' || text[i] == '?' || text[i] == '\n') {
int length = strlen(text);
for (int k = i + 1; k < length; k++) {
text[k - 1] = text[k];
}
text[length - 1] = '\0';
i--;
}
}
}
int extract_and_count(char *source, int count[]) {
int wordCounter = 0;
char string[MAX_WORD_SIZE] = {'\0'};
for (int i = 0, k = 0; i < strlen(source); i++, k++) {
if (source[i] != ' ') {
string[k] = source[i];
} else {
if (string[0] == '\0') {
break;
}
int index = indexInWords(string);
if (index == -1) {
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
} else {
count[index] += 1;
}
clearArray(string);
k = -1;
}
}
if (string[0] != '\0') {
int index = indexInWords(string);
if (index == -1) {
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
} else {
count[index] += 1;
}
}
return wordCounter;
}
void clearArray(char array[]) {
memset(array, 0, strlen(array));
}
int indexInWords(char string[]) {
for (int i = 0; i < MAX_WORD_COUNT; i++) {
if (equals(words[i], string)) {
return i;
}
}
return -1;
}
void print(int countOfWords, int count[]) {
for (int i = 0; i < countOfWords; i++) {
printf("%s : %d\n", words[i], count[i]);
}
}
bool equals(char string1[], char string2[]) {
return strcmp(string1, string2) == 0;
}
The next most significant issue I see is you don't keep track of how many entries in words[][] are used, so indexInWords() could easily wander off making comparisons against uninitialized memory.
In extract_and_count you break out of the for-loop when you find 2 spaces. Also you did not check for the last word of source. Changed it to:
int extract_and_count(char *source, int *count){
int wordCounter = 0;
char string[80];
int i = 0, k = 0;
clearArray(string);
for(; i < strlen(source)+1;++i, ++k){
if(source[i] != ' ' && source[i] != 0){
string[k] = source[i];
}else{
if(string[0] != '\0'){
int index = indexInWords(string);
if(index == -1){
strcpy(words[wordCounter], string);
count[wordCounter] = 1;
wordCounter++;
}else{
count[index] += 1;
} }
clearArray(string);
k = -1;
}
}
return wordCounter;
}

unexpected input value; log10 failed

When I write:
printf("%f; ", massive[i]);
Where:
double** InputSystemOfLinearEquationsByFile(FILE* file) {
char* inputc = (char*)malloc(quiteenoughelements * sizeof(char));
int thenumberofvaribles = 0;
int thenumberofequations = 0;
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
thenumberofvaribles = atoi(inputc);
if (thenumberofvaribles <= 0) {
return NULL;
}
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
thenumberofequations = atoi(inputc);
if (thenumberofequations <= 0) {
return NULL;
}
double** answer = (double**)malloc(thenumberofequations*sizeof(double*));
for (int i = 0; i < thenumberofequations; i++) {
answer[i] = (double*)malloc((thenumberofvaribles + 1)*sizeof(double));
}
for (int i = 0; i < thenumberofequations; i++) {
for (int j = 0; j < thenumberofvaribles; j++) {
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
answer[i][j] = atof(inputc);
}
}
for (int i = 0; i < thenumberofequations; i++) {
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
answer[i][thenumberofvaribles] = atof(inputc);
}
free(inputc);
return answer;
}
void SwapStrokes(double** matrix, const unsigned int stroke1index, const unsigned int stroke2index) {
double* temp = matrix[stroke1index];
matrix[stroke1index] = matrix[stroke2index];
matrix[stroke2index] = temp;
temp = NULL;
}
unsigned char ZeroCheck(double** matrix, const unsigned int currentstroke, const unsigned int currentcolumn, const unsigned int numberofequations) {
int numberofnotzerocolumn = currentstroke;
while ((fabs(matrix[numberofnotzerocolumn][currentcolumn]) < accuracy) || (matrix[numberofnotzerocolumn][currentcolumn] != matrix[numberofnotzerocolumn][currentcolumn])) {
numberofnotzerocolumn++;
if (numberofnotzerocolumn == numberofequations) {
return 1;
}
}
if (numberofnotzerocolumn != currentstroke) {
SwapStrokes(matrix, currentstroke, numberofnotzerocolumn);
}
return 0;
}
void JordanException(double** matrix, const unsigned int currentstroke, const unsigned int currentcolumn, const unsigned int numberofvars, const unsigned int numberofequations) {
int optionalcolumn = 0;
int optionalstroke = 0;
for (optionalstroke = 0; optionalstroke < currentstroke; optionalstroke++) {
for (optionalcolumn = 0; optionalcolumn < currentcolumn; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
optionalcolumn++;
for (optionalcolumn; optionalcolumn <= numberofvars; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
}
for (optionalstroke = currentstroke + 1; optionalstroke < numberofequations; optionalstroke++) {
for (optionalcolumn = 0; optionalcolumn < currentcolumn; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
optionalcolumn++;
for (optionalcolumn; optionalcolumn <= numberofvars; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
}
for (optionalcolumn = 0; optionalcolumn < currentcolumn; optionalcolumn++) {
matrix[currentstroke][optionalcolumn] /= matrix[currentstroke][currentcolumn];
}
optionalcolumn++;
for (optionalcolumn; optionalcolumn <= numberofvars; optionalcolumn++) {
matrix[currentstroke][optionalcolumn] /= matrix[currentstroke][currentcolumn];
}
for (optionalstroke = 0; optionalstroke < numberofequations; optionalstroke++) {
matrix[optionalstroke][currentcolumn] = 0.;
}
matrix[currentstroke][currentcolumn] = 1.;
}
double* JordanMethod(double** matrix, const unsigned int numberofvars, const unsigned int numberofequations) {
if (numberofvars > numberofequations) {
return NULL;
}
else {
unsigned int currentcolumn = 0;
unsigned int currentstroke = 0;
while ((currentcolumn < numberofvars) && (currentstroke < numberofequations)) {
if (ZeroCheck(matrix, currentstroke, currentcolumn, numberofequations) == 1) {
return NULL;
}
JordanException(matrix, currentstroke, currentcolumn, numberofvars, numberofequations);
currentstroke++;
currentcolumn++;
}
double* answer = (double*)malloc(numberofvars * sizeof(double));
for (currentstroke = 0; currentstroke < numberofvars; currentstroke++) {
if ((fabs(matrix[currentstroke][numberofvars]) < accuracy) || (matrix[currentstroke][numberofvars] != matrix[currentstroke][numberofvars])){
matrix[currentstroke][numberofvars] = 0.;
}
answer[currentstroke] = matrix[currentstroke][numberofvars];
}
return answer;
}
}
void WriteMassive(double* massive, unsigned int numberofelements, FILE* file) {
if ((massive != NULL) && (file != NULL)){
for (unsigned int i = 0; i < numberofelements; i++) {
fprintf(file, "%f; ", massive[i]);
}
fprintf(file, "\n");
}
}
int main(int argc, char **argv)
{
double* matrixa = NULL;
double** matrix = NULL;
FILE* file;
FILE* output;
file = fopen("File.txt", "r");
matrix = InputSystemOfLinearEquationsByFile(file);
matrixa = JordanMethod(matrix, 4, 4);
WriteMassive(matrixa, 4, output);
fclose(file);
system("pause");
return 0;
}
My file has got:
4
4
2 -1 5 7
3 3,5 4 -5
-7 -3 7,2 5,3
4 3 2,1 -3,5
I face this bug, when i=0:
> Debug Assertion Failed! Program: ...ConsoleApplication1.exe File:
> minkernel\crts\ucrt\src\appcrt\convert\cfout.cpp Line: 126 Expression:
> ("unexpected input value; log10 failed, 0)
What should I do?
P.s. While debugging I move cursed to massive[i] and visual studio show that it has normal value (something like 6.29...).
I've tried my code on VS 2013 (instead of 2015) and... It worked! Idk how it works, maybe it just problem with my computer.

Pointers and Dynamic Memory

I have a function that returns a pointer to an array. I'm running it in a loop and free() seems to be giving me problems. I'm not sure where, but it appears that somewhere in the main loop the memory that I'm trying to free is being used. I'm using Xcode 3.2.1 in 10.6 | Debug | x86_64 build.
The program will run through the main loop one time; the second time it encounters the free() it gives me the following error:
malloc: *** error for object 0x100100180: incorrect checksum for freed object -
object was probably modified after being freed.
Can someone point out (no pun intended) what I'm doing wrong with pointers here?
Here is the program:
int main(int argc, char **argv) {
int *partition;
int lowerLimit;
int upperLimit;
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
// these loops are part of the Atkins Sieve implementation
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Why is intAlloc not returning int* ?
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if(ptr == NULL) {
printf("Error: NULL pointer\n");
exit(1);
}
return ptr; //like this
}
EDIT (after your update):
On atkinsPrimes() where is filtered being intAlloc()ed?
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int resultsSize;
primes = intAlloc(limit+1);
// ...
initialPrimes = intAlloc(2);
// ...
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered); // Where was it intAlloc()ed?
results[resultsSize] = 0; // make the array 0-terminated to make it easier to work with
return results;
}
EDIT (after your N-th update):
This is a compilable version of your code. It ran smooth on my machine, no crashes. Compiled with g++ (due to declarations of variables inside the for statement):
g++ (Debian 4.3.2-1.1) 4.3.2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int *goldbachPartition(int x);
int *atkinsPrimes(int limit);
int trueCount(int *subject, int arraySize);
int intCount(int *subject) ;
void intFillArray(int *subject, int arraySize, int value);
int *intFilterArrayKeys(int *subject, int arraySize);
int *intAlloc(int amount);
void printOutput(int num1, int num2, int rep) ;
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2);
int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./program <lower> <upper>\n");
return 0;
}
int *partition;
int lowerLimit = atoi(argv[1]);
int upperLimit = atoi(argv[2]);
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Since you are still omitting some source, I can only imagine that the problem is hidden there.
EDIT: (my last update)
To assist your debugging, you should replace your main() function by the one below:
int main(int argc, char **argv)
{
int *primes = NULL;
primes = atkinsPrimes(44); // Evil magic number
free(primes);
return 0;
}
Having a minimal example to reproduce the behavior you pointed out is much better then the whole thing. Have fun with atkinsPrimes(44)

Resources