Why does my code give AddressSanitizer error (ie attempting to free on address which was not malloc-ed)? I did calloc new memory, but when I attempt to free them, I'll run into an error? Any form of help or advice would be appreciated, thank you!
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[100];
char gender; // 'M' for Male, 'F' for Female
} person;
bool not_in_arr(char *name, char **arr, int size) {
for (int i = 0; i < size; i++) {
if (strcmp(name, arr[i]) == 0) {
return false;
}
}
return true;
}
char **get_lucky_ones(person table[], int n, int *r_size) {
person *new = calloc(n * 2, sizeof(person));
for (int i = 0; i < n; i++) {
new[i] = table[i];
new[n + i] = table[i];
}
char **new_arr = calloc(n, sizeof(char *));
int index = 0;
for (int i = 1; i < 2 * n - 1; i++) {
char gender = new[i].gender;
if (new[i + 1].gender != gender &&new[i - 1].gender != gender) {
char *name = new[i].name;
if (not_in_arr(name, new_arr, index)) {
new_arr[index] = name;
//printf("%s\n", new_arr[index]);
index++;
}
}
}
*r_size = index;
//free(new);
return new_arr;
}
int main(void) {
{
person table[] = {{"apple", 'M'}, {"berry", 'F'}, {"cherry", 'F'},
{"durian", 'M'},
{"fig", 'F'}};
int r_size;
char **result = get_lucky_ones(table, sizeof(table) / sizeof(table[0]),
&r_size);
for (int i = 0; i < r_size; i++) {
printf("%s ", result[i]);
free(result[i]);
}
free(result);
printf("\n");
}
}
new_arr points at the memory allocated by the new array. So if you free() new, then new_arr points at garbage. Maybe you want to make a hardcopy here: new_arr[index] = name;.
Related
I have written some code on to find the number of times the characters repeated in the string.Considered 2 pointers and allocated memory dynamically, then input the string into one of the pointers.Then copying the characters without redundancies into the another pointer and finally comparing it, incrementing the count and printing to the screen.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void string_cpy(char *from, char *to);
int len(char *p);
int main()
{
char *name, *copy, *hold;
int i, j, lent, count = 0, length;
name = (char *)calloc(25, sizeof(char));
copy = (char *)calloc(25, sizeof(char));
printf("Give a string:");
scanf("%s", name);
puts("");
string_cpy(name, copy);
hold = name;
lent = len(copy); //l=4
length = len(name); //lenght = 5
printf("Characters and their corresponding frequencies\n");
for (i = 0; i < lent; ++i)
{
for (j = 0; j < length;)
{
if (*(copy) == *(name))
{
++count;
++name;
++j;
}
else
{
++j;
++name;
}
}
name = hold;
printf("%c-%d\n", *(copy), count);
count = 0;
++copy;
}
free(name);
free(copy);
return 0;
}
void string_cpy(char *from, char *to)
{
int i, j, k, l, ex;
char key;
l = len(from); //l=5
char *t = to;
for (i = 0, j = 0; i < l; ++i)
{
key = *(from + i);
ex = 0;
for (k = 0; k < i; ++k)
{
if (*(to + k) == key)
{
ex = 1;
}
}
if (!ex)
{ //if(ex==0)
strcpy((to + j), (from + i));
++j;
}
}
}
int len(char *p)
{
int leng = 0;
while (*p != '\0')
{
++leng;
++p;
}
return leng;
}
when I try to free() up both the pointers or the '''char *copy''' it throws me an error
->malloc: *** error for object 0x120e06884: pointer being freed was not allocated
->malloc: *** set a breakpoint in malloc_error_break to debug
This was done on my Mac OS
You change the value of the calloced pointer. It does not reference anymore the allocated memory block.
++copy;
I want to make a simple program (but difficult for me), which will find contacts by letters (parts of the name are entered using numbers) and by numbers (parts of the number). Input - numbers, from the standard input (txt file), output - contacts that contain these numbers (letters). The contact file looks like
(name)
(number)
(name)
(…)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (32)
/*
IN :
contacts.txt :
Sad Mirrow
38074025
Deniel Kovalski
78032596
Miky Trance
88055535
Martin Worried
77432651
96 [key number from standard entry]
OUT:
Deniel Kovalski
[because 96 matches in his number]
Martin Worried
[96 matches in his name Wo]
*/
typedef struct Contact {
char* name;
char* number;
} Contact;
char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
bool find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return true;
}
return false;
}
bool matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return true;
}
return false;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
size_t arrSize = 32;
Contact* contacts = malloc(arrSize * sizeof(Contact));
int k = 0;
size_t nameSize = MAX_NAME;
size_t numSize = MAX_NUM;
char *nameBuf = malloc(MAX_NAME);
char *numBuf = malloc(MAX_NUM);
FILE* f = fopen("contacts.txt", "r");
while (fgets(nameBuf, nameSize, f)
&& fgets(numBuf, numSize, f)){
contacts[k].name = malloc(MAX_NAME);
contacts[k].number = malloc(MAX_NUM);
strcpy(contacts[k].name, nameBuf);
strcpy(contacts[k].number, numBuf);
k++;
if (k == arrSize);
arrSize <<= 1;
contacts = realloc(contacts, arrSize * sizeof(Contact));
}
for (int i = 0; i < k; i++){
bool matchesName = matches(contacts[i].name, key);
bool matchesNumber = matches(contacts[i].number, key);
if (matchesName || matchesNumber)
printf("%s\n", contacts[i].name);
}
for (int i = 0; i < k; i++){
free(contacts[i].name);
free(contacts[i].number);
}
free(contacts);
free(nameBuf);
free(numBuf);
fclose(f);
return 0;
}
At first we did as we could. Then was a time to fulfill the conditions of the task and the problem came. It needs to be done without malloc/calloc/fopen. I tried to fix everything, but I ran into a problem that the program does not work and it seems to me that I'm confused.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NAME (128)
#define MAX_NUM (64)
struct Folio
{
char name[1000];
char num[1000];
};
static char matchTable[10][9] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
int find(char c, char key){
int j = key - '0';
for (int i = 0; matchTable[j][i] != '\0'; i++){
if (c == matchTable[j][i])
return 1;
}
return 0;
}
int matches(char* src, char* key){
unsigned int i,j;
for (i = 0; src[i] != '\0'; i++){
unsigned int tmp = i;
for (j = 0; key[j] != '\0'; j++){
if (find(src[tmp], key[j]))
tmp++;
else
break;
}
if (j == strlen(key))
return 1;
}
return 0;
}
int main(){
char key[MAX_NUM];
scanf("%s", key);
struct Folio contacts[42]; //Entry entries[42]
int contacts_count = 0; //entries_count = 0;
//FILE* f = fopen("seznam.txt", "r");
char name[1000];
char num[1000]; //number[1000]
while (fgets(name, MAX_NAME, stdin) != NULL && fgets(num, MAX_NUM, stdin) != NULL)
{
// copy to struct
strcpy(contacts[contacts_count].name, name);
strcpy(contacts[contacts_count].num, num);
contacts_count++;
}
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[contacts_count].name, contacts[contacts_count].num);
}
//fclose(f);
return 0;
}
I want to ask the help of experienced programmers.
matchTable[10][9] is too small to save "7pqrsPQRS" as a string as needed in matchTable[j][i] != '\0';. Needs 10.
Suggest
//static char matchTable[10][9] = {
// "0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
// "5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
//};
static char *matchTable[10] = {
"0+", "1", "2abcABC", "3defDEF", "4ghiGHI",
"5jklJKL", "6mnoMNO", "7pqrsPQRS", "8tuvTUV", "9wxyWXY"
};
Perhaps other issues too.
I believe the main issue is the the search logic. Code loops over all contacts, but will attempt a match against the a non-existing contacts entry.
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[contacts_count].name, key);
int matchesNumber = matches(contacts[contacts_count].num, key);
...
Should this use the i-th contacts ?
for (int i = 0; i < contacts_count; i++){
int matchesName = matches(contacts[i].name, key);
int matchesNumber = matches(contacts[i].num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", contacts[i].name, contacts[contacts_count].num);
}
Or even
for (int i = 0; i < contacts_count; i++){
struct Folio con_p = &contacts[i] ;
int matchesName = matches(con_p->name, key);
int matchesNumber = matches(con_p->num, key);
if (matchesName || matchesNumber)
printf("%s%s\n", con_p->name, con_p->num);
}
Also take a look at answer from chux - Reinstate Monica
link of program question https://www.hackerrank.com/challenges/cut-the-sticks/problem
#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* readline();
char** split_string(char*);
int* cutTheSticks(int arr_count, int* arr, int* result_count) {
int c=arr_count,min;
int result[c];
for (int k=0;k<arr_count;k++){
min = *arr;
for (int i = 0; i < c; i++) {
if (*(arr + i) < min)
min = *(arr + i);
}
int count=0;
for (int i=0; i < c; i++) {
if(min==*(arr+i))count++;
}
for (int i=0; i < c; i++) {
*(arr+i)=*(arr+i)-min;
}
int temp=0;
for(int i=0;i<c;i++){
for(int x=i;x<c;x++){
if(*(arr+i)<*(arr+x)){
temp=*(arr+i);
*(arr+i)=*(arr+x);
*(arr+x)=temp;
}
}
}
result[k]= c;
*(result_count)=*(result_count)+1;
c = c - count;
if(c==0)break;
}
return result;
}
int main()
{
FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");
char* n_endptr;
char* n_str = readline();
int n = strtol(n_str, &n_endptr, 10);
if (n_endptr == n_str || *n_endptr != '\0') { exit(EXIT_FAILURE); }
char** arr_temp = split_string(readline());
int* arr = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
char* arr_item_endptr;
char* arr_item_str = *(arr_temp + i);
int arr_item = strtol(arr_item_str, &arr_item_endptr, 10);
if (arr_item_endptr == arr_item_str || *arr_item_endptr != '\0') {
exit(EXIT_FAILURE); }
*(arr + i) = arr_item;
}
int arr_count = n;
int result_count;
int* result = cutTheSticks(arr_count, arr, &result_count);
for (int i = 0; i < result_count; i++) {
fprintf(fptr, "%d", *(result + i));
if (i != result_count - 1) {
fprintf(fptr, "\n");
}
}
fprintf(fptr, "\n");
fclose(fptr);
return 0;
}
char* readline() {
size_t alloc_length = 1024;
size_t data_length = 0;
char* data = malloc(alloc_length);
while (true) {
char* cursor = data + data_length;
char* line = fgets(cursor, alloc_length - data_length, stdin);
if (!line) { break; }
data_length += strlen(cursor);
if (data_length < alloc_length - 1 || data[data_length - 1] == '\n') {
break; }
size_t new_length = alloc_length << 1;
data = realloc(data, new_length);
if (!data) { break; }
alloc_length = new_length;
}
if (data[data_length - 1] == '\n') {
data[data_length - 1] = '\0';
}
data = realloc(data, data_length);
return data;
}
char** split_string(char* str) {
char** splits = NULL;
char* token = strtok(str, " ");
int spaces = 0;
while (token) {
splits = realloc(splits, sizeof(char*) * ++spaces);
if (!splits) {
return splits;
}
splits[spaces - 1] = token;
token = strtok(NULL, " ");
}
return splits;
}
This above code is my full code from harkerrank, below is main fuction.
i can't able to return my pointer value from cutTheStricks to main function.
// Please store the size of the integer array to be returned in
result_count
pointer. For example,
// int a[3] = {1, 2, 3};
//
// *result_count = 3;
//
// return a;
int* cutTheSticks(int arr_count, int* arr, int* result_count) {
int c=arr_count,min;
int result[c];
for (int k=0;k<arr_count;k++){
min = *arr;
for (int i = 0; i < c; i++) {
if (*(arr + i) < min)
min = *(arr + i);
}
int count=0;
for (int i=0; i < c; i++) {
if(min==*(arr+i))count++;
}
for (int i=0; i < c; i++) {
*(arr+i)=*(arr+i)-min;
}
int temp=0;
for(int i=0;i<c;i++){
for(int x=i;x<c;x++){
if(*(arr+i)<*(arr+x)){
temp=*(arr+i);
*(arr+i)=*(arr+x);
*(arr+x)=temp;
}
}
}
result[k]= c;
*(result_count)=*(result_count)+1;
c = c - count;
if(c==0)break;
}
return result;
}
I am not getting any output but my logic is correct.
I know there is there is something missing therefore i can't able to return my output;
I can't figure out which pointer value(*result or *result_count ) is not passing
or what is happening i can't able to figure out.
You are returning the address of a local array whose life time ends with the function, change
int result[c];
to
int *result = malloc(sizeof(*result) * c);
You are also using the address of an uninitialized value here:
*(result_count)=*(result_count)+1;
change
int result_count;
to
int result_count = 0;
I am writing a tool to scan all the nodes on a network but I have ran in to a problem. I'm writing the tool in C but I'm new to the language so I'm not sure how the iterate through the address range.
The user will give the argument 192.168.*.* and it will create every IP address in that range, e.g. 192.168.1.1, 192.168.1.2, 192.168.1.3 and then eventually 192.168.2.1, 192.168.2.2, 192.168.2.3 etc.
My previous code was:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void scanner(int s)
{
char addr[20];
for (int i = 0; i < 255; ++i)
{
sprintf(addr, "192.168.%d.%d", s, i);
printf("%s\n", addr);
}
}
int main()
{
for (int i = 0; i < 255; ++i)
{
scanner(i);
}
return 0;
}
But I don't know how to run this from the user input.
You can take the inputs from the user using the scanf function. I have updated your code to use the same -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int addr_byte_0;
int addr_byte_1;
void scanner(int s)
{
char addr[200];
int i;
for (i = 0; i < 255; ++i)
{
sprintf(addr, "%d.%d.%d.%d", addr_byte_0, addr_byte_1, s, i);
printf("%s\n", addr);
}
}
int main()
{
int i;
//printf("Enter the first byte of the address: ");
scanf ("%d", &addr_byte_0);
//printf("Enter the second byte of the address: ");
scanf ("%d", &addr_byte_1);
for (i = 0; i < 255; ++i)
{
scanner(i);
}
return 0;
}
Also, as per C standards you cannot declare a variable inside the for loop. Hence I have moved the declaration out of the for loop. Hope this helps!
Inspired by (e.g. python-) generators, my solution doesn't perform dynamic memory allocation and and has constant memory consumption. I don't like that I currently rely on a do while loop. Also the explicit check for ig->num_wildcards == 0 is ugly. Anyways:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define IP_OCTETS 4
#define MAX_UCHAR 255
typedef struct {
int wildcard_pos[IP_OCTETS];
int num_wildcards;
int counter[IP_OCTETS];
int octet[IP_OCTETS];
} ip_generator;
char* mystrsep(char** stringp, const char* delim)
{
char* start = *stringp;
char* p;
p = (start != NULL) ? strpbrk(start, delim) : NULL;
if (p == NULL)
{
*stringp = NULL;
}
else
{
*p = '\0';
*stringp = p + 1;
}
return start;
}
void init_ip_gen(ip_generator *ig, char* ip_mask)
{
char *token, *string;
char* ip_mask_ptr = ip_mask;
const char delimiters[] = ".";
int i = 0;
while ((token = mystrsep(&ip_mask_ptr, delimiters)) != NULL)
{
ig->wildcard_pos[i] = -1;
if (strcmp(token, "*") == 0)
{
ig->wildcard_pos[ig->num_wildcards] = i;
ig->counter[ig->num_wildcards] = 1;
ig->num_wildcards++;
}
else
{
ig->octet[i] = atoi(token);
}
i++;
}
}
int ig_next(ip_generator *ig)
{
int i;
int carry = 1;
if (ig->num_wildcards == 0)
{
return 0;
}
for (i = ig->num_wildcards - 1; i >= 0; i--)
{
if (carry == 1)
{
if (ig->counter[i] == MAX_UCHAR)
{
ig->counter[i] = 1;
}
else
{
ig->counter[i]++;
carry = 0;
}
}
if (carry == 0)
{
break;
}
if (i == 0 && carry == 1)
{
return 0;
}
}
return 1;
}
void generate_ip(ip_generator *ig, char *ip)
{
int i;
int j = 0;
int oct[IP_OCTETS];
for (i = 0; i < IP_OCTETS; i++)
{
if (i == ig->wildcard_pos[j])
{
oct[i] = ig->counter[j];
j++;
}
else
{
oct[i] = ig->octet[i];
}
}
sprintf(ip, "%d.%d.%d.%d", oct[0], oct[1], oct[2], oct[3]);
}
int main()
{
char ip_mask[] = "192.*.10.*";
//char ip_mask[] = "192.1.10.123";
ip_generator ig;
memset(&ig, 0, sizeof(ig));
init_ip_gen(&ig, ip_mask);
char ip[32];
memset(ip, 0, sizeof(ip));
do
{
generate_ip(&ig, ip);
printf("%s\n", ip);
} while (ig_next(&ig));
return 0;
}
I am learning about arrays and was wondering if someone can help me out. I have an array of strings and need to create a new string which is a concatenation of all the array elements. The problem I'm having is I'm only able to print the first string in my array, not all of them. I understand there is a null at the end of each string in my array so how would I work around that issue? Maybe 2d array? By the way I'm not allowed to use any string manipulation functions from string.h. Thank you.
#include <stdio.h>
#include <stdlib.h>
int findLength(char array[])
{
int i = 0;
for (i = 0; array[i] != '\0'; i++)
{
}
return i;
}
void arrayToString(char string[])
{
int n = 0;
int i = 0;
int l = findLength(string);
char *finalString;
finalString = malloc(l * sizeof(char));
for (i = 0; string[i] != '\0'; i++) {
finalString[n] = string[i];
n++;
}
for (i = 0; finalString[i] != '\0'; i++) {
printf("%c", finalString[i]);
}
}
int main(int argc, const char * argv[])
{
char *color[] = { "red", "blue", "red" };
arrayToString(*color);
return 0;
}
Change your function arrayToString to have two arguments.one of type char ** and the second of type size_t defining the number of strings.Also let its return value to be char * to return a pointer to the allocated memory.finally don't forget to free this memory.
#include <stdio.h>
#include <stdlib.h>
int findLength(char array[]) {
int i = 0;
for (i = 0; array[i] != '\0'; i++) {
}
return i;
}
char* arrayToString(char **string, size_t size) {
int bigSize = 0, len;
int i = 0, j, k;
for (j = 0; j < size; j++) {
bigSize += findLength(string[j]);
}
char *bigstring = (char *)malloc(bigSize + 1);
for (j = 0; j < size; j++) {
len = findLength(string[j]);
for (k = 0; k < len; k++) {
bigstring[i++] = string[j][k];
}
}
bigstring[i] = '\0';
return bigstring;
}
int main(int argc, const char * argv[])
{
char *color[] = { "red", "blue", "red" };
char *bigstring = arrayToString(color, 3);
printf("%s\n", bigstring);
free(bigstring);
return 0;
}
you have several problems in your code, here is the fixed version with comments:
size_t findLength(char* array[]) {
size_t l = 0;
while (char *t = *array++)
while (*t++)
l++;
return l;
}
void copyAll(char* array[], char* out) {
while (char *t = *array++)
while (*t)
*out++ = *t++; // copy every symbol from every line into out string
*out = '\0'; // append last null-terminator
}
void arrayToString(char* array[]) {
char* finalString = malloc((findLength(array) + 1) * sizeof(char)); // allocate + 1 symbol for null terminator
copyAll(array, finalString);
printf("%s", finalString);
free(finalString); // don't forget to release memory
}
int main(int argc, char* argv[]) {
char* color[] = { "red", "blue", "red", 0 }; // you should add array terminator as well
arrayToString(color);
return 0;
}