Everything seems to work fine while dynamically creating the array
but core dumped while trying to print it backwards.
It managed to print only the last string and then segmentation fault.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
void init_array(void ***pt, int *ptlen) {
*pt=NULL;
*ptlen=0;
}
void trim_array(void ***pt, int *ptlen, int len) {
*pt=(void**)realloc(*pt, len*sizeof(void*));
*ptlen=len;
}
void write_array(void ***pt, int *ptlen, int pos, void *v) {
if (pos >= *ptlen)
trim_array(pt, ptlen, pos+1);
*pt[pos]=v;
}
void *read_array(void ***pt, int *ptlen, int pos) {
return(*pt[pos]);
}
void destroy_array(void ***pt, int *ptlen) {
trim_array(pt, ptlen, 0);
*pt=NULL;
}
int main(int argc, char *argv[]) {
void **t;
int tlen;
void ***pt = &t;
int *ptlen = &tlen;
char s[256],*p; int i;
init_array(pt, ptlen);
i = 0;
do {
printf("give name:\n");
scanf("%255s",s);
write_array(pt, ptlen, i, (void*)strdup(s));
i++;
} while (strcmp(s,"end"));
for (--i; i>=0; i--) {
p = (char*)read_array(pt, ptlen, i);
printf("%s\n",p);
free(p);
}
destroy_array(pt, ptlen);
return(0);
}
The [] operator has a higher precedence than the * operator. You need to change:
*pt[pos]
to:
(*pt)[pos]
in both places where it occurs.
This error is a direct result of writing almost deliberately confusing code with runaway indirection. You'd save yourself a lot of trouble and make things much easier if you wrapped a lot of this stuff in a struct and created some proper interface functions for it.
Something like this would be a bit better form (although "array" is not really a great name for this data structure):
main.c:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "array.h"
#define MAX_BUFFER_LEN 255
int main(void) {
Array myarray = array_init(10, true);
/* Loop for input until user enters "end" */
char buffer[MAX_BUFFER_LEN];
while ( true ) {
printf("Give name: ");
fflush(stdout);
/* Get input and remove trailing '\n' if necessary */
fgets(buffer, MAX_BUFFER_LEN, stdin);
size_t last = strlen(buffer) - 1;
if ( buffer[last] == '\n' ) {
buffer[last] = '\0';
}
/* Terminate loop on "end" without adding to array... */
if ( !strcmp(buffer, "end") ) {
break;
}
/* ...or append input to array and continue loop */
array_append(myarray, strdup(buffer));
};
/* Output contents of array */
size_t n = array_size(myarray);
for ( size_t i = 0; i < n; ++i ) {
char * data = array_getdata(myarray, i);
printf("%zu: %s\n", i + 1, data);
}
/* Clean up and exit */
array_destroy(myarray);
return EXIT_SUCCESS;
}
array.h:
#ifndef ARRAY_TYPE_H
#define ARRAY_TYPE_H
#include <stdbool.h>
typedef struct array_type * Array; /* Opaque type for user */
Array array_init(const size_t capacity, const bool free_on_delete);
void array_append(Array array, void * data);
size_t array_size(const Array array);
void * array_getdata(Array array, const size_t index);
void array_deletetop(Array array);
void array_destroy(Array array);
#endif /* ARRAY_TYPE_H */
array.c:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "array.h"
/* Struct definition is visible only to implementation */
struct array_type {
void ** elements;
size_t capacity;
size_t top;
bool free_on_delete;
};
/* Static functions used by the implementation */
static bool array_isfull(Array array) {
return (array->top + 1) == array->capacity;
}
static void array_resize(Array array, const size_t new_capacity) {
array->capacity = new_capacity;
array->elements = realloc(array->elements,
array->capacity * sizeof (*array->elements));
if ( array->elements == NULL ) {
fputs("Error allocating memory.", stderr);
exit(EXIT_FAILURE);
}
}
/* Interface functions */
Array array_init(const size_t capacity, const bool free_on_delete) {
struct array_type * new_array = malloc(sizeof *new_array);
if ( new_array == NULL ) {
fputs("Error allocating memory.", stderr);
exit(EXIT_FAILURE);
}
new_array->elements = malloc(capacity * sizeof (*new_array->elements));
if ( new_array->elements == NULL ) {
fputs("Error allocating memory.", stderr);
exit(EXIT_FAILURE);
}
new_array->capacity = capacity;
new_array->top = 0;
new_array->free_on_delete = free_on_delete;
return new_array;
}
void array_append(Array array, void * data) {
if ( array_isfull(array) ) {
array_resize(array, array->capacity * 2);
}
array->elements[array->top++] = data;
}
size_t array_size(const Array array) {
return array->top;
}
void * array_getdata(Array array, const size_t index) {
return array->elements[index];
}
void array_deletetop(Array array) {
if ( array->free_on_delete ) {
free(array->elements[array->top - 1]);
}
array->elements[--array->top] = NULL;
}
void array_destroy(Array array) {
while ( array->top > 0 ) {
array_deletetop(array);
}
free(array->elements);
free(array);
}
Sample output:
paul#local:~/src/c/scratch/array$ ./array
Give name: Dave Dee
Give name: Dozy
Give name: Beaky
Give name: Mick
Give name: Titch
Give name: end
1: Dave Dee
2: Dozy
3: Beaky
4: Mick
5: Titch
paul#local:~/src/c/scratch/array$
Related
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct kezdo
{
int mennyi;
char betu;
}KEZDO;
int main(int argc, char* argv[])
{
int j;
int i;
int db=0;
int volt=0;
char sajt[22];
FILE* f=fopen(argv[1], "r");
if(f==NULL)
{
fprintf(stderr, "Hiba a fajl megnyitasaban!");
}
int k = 20;
KEZDO t[k];
KEZDO tmp;
for(i=0;i<k;i++)
{
t[i].mennyi = 0;
}
while(fgets(sajt,22,f)!=0)
{
if(sajt[strlen(sajt)-1] == '\n')
{
sajt[strlen(sajt)-1] = '\0';
}
for(i=0;i<k;i++)
{
if(t[i].betu == toupper(sajt[0]))
{
t[i].mennyi++;
volt=1;
}
}
if(volt==0)
{
t[db].betu = toupper(sajt[0]);
t[db].mennyi++;
db++;
}
else
{
volt = 0;
}
}
for(i=0;i<db;i++)
{
printf("%c: %d\n", t[i].betu, t[i].mennyi);
}
return 0;
}
I tried strcmp and stricmp but neither worked. I tried to fully change the struct by sorting the struct properties. When the struct properties are sorted it doesn't work, but it worked before in a non-sorted order. What is preventing output when the struct properties are sorted?
As i can see in your code, you want to sort on char betu. One way to sort structures is via qsort but that'd require comparator function stated below:
int compare(const void *void_a, const void *void_b)
{
const KEZDO *a = void_a;
const KEZDO *b = void_b;
return (a->betu) < (b->betu);
}
//Perform sort like this;
qsort((void *) &t, db, sizeof(KEZDO) , compare );
Moreover, qsort is in #include <stdlib.h>
table.h:
#ifndef table_h
#define table_h
// The object:
typedef struct Pair
{
char* name;
int number;
} Pair;
int comp_pair(const void* lhs, const void* rhs)
{
Pair* lp = (Pair*) lhs;
Pair* rp = (Pair*) rhs;
const char* ln = lp->name;
const char* rn = rp->name;
return strcmp(ln, rn);
}
// The array and associated functions:
size_t table_capacity;
size_t table_size;
Pair* table; // <------ Global variables -------------------
Pair* create_table (size_t capacity)
{
Pair* p = 0;
p = (Pair*) malloc(sizeof(*p) * capacity);
if (p == NULL && capacity > 0)
{
perror("create_table()::bad allocation!\n");
exit(-1);
}
table_capacity = capacity;
return p;
}
void insert (Pair* table, const char* name, int number)
{
Pair* p = (Pair*) malloc(sizeof(*p));
if (p == NULL)
{
perror("insert::bad allocation!\n");
exit(-1);
}
p->name = name;
p->number = number;
table[table_size++] = *p;
}
void print_table(Pair p[], size_t size)
{
size_t i = 0;
for (i; i < size; ++i)
{
printf("%s -> %d\n", p[i].name, p[i].number);
}
}
#endif
main.c:
#include <stdio.h>
#include <stdlib.h> // qsort()
#include <string.h> // strcmp()
#include <stddef.h> // size_t
#include "table.h"
int main()
{
char* names [ ] = { "bla1", "bla2", "bla3", "bla4", "bla5"};
int numbers [ ] = { 1, 2, 3, 4, 5 };
size_t s = 5;
size_t i = 0;
table = create_table(s);
for (i; i < s; ++i)
{
insert(table, names[i], numbers[i]);
}
qsort(table, table_size, sizeof(Pair), comp_pair);
print_table(table, table_size);
getchar();
free(table);
}
When I try to use qsort(), (debugging) the above code generates the following error:
Access violation reading location 0x65727541.
Questions:
Is the function comp_pair() correct?
What size should I pass as a third parameter in qsort(), the current sizeof(Pair) or the size of the actually compared types, i.e. char*?
I am having an error with the code we are using, was wondering if someone could help debug. Seems like we are getting a malloc error. Thanks.
void readWords(char norm_word[MAXSIZE], Word ** array) {
int i = 0;
bool found = false;
int result = 0;
Word * current_pointer = malloc (sizeof(Word*));//creates a temporary variable for each pointer in the array
for (i=0; i<word_counter; i++) {
current_pointer = *(array+i); //accesses the current pointer
result = strcmp(norm_word, (current_pointer -> word)); //compares the string to each stored string
if (result == 0) {
found = true;
(current_pointer->freq)++;
break;
}
}
if(!found) {
if(pointer_counter == word_counter) {
array = realloc(array, sizeof(array)*2);
pointer_counter*=2;
}
Word * new_pointer = (Word*) malloc (sizeof(Word*));
strcpy(new_pointer -> word, norm_word);
*(array + (pointer_counter - 1)) = new_pointer;
word_counter++;
}
;
}
All pointers have the same size on your system. So a sizeof always returns the same size for any pointer. You want to allocate for the structure, so you need to use sizeof on the name without the star. malloc will return the pointer to that block of memory afterwards.
Here is a short implementation:
#include <iostream>
#include <string>
typedef struct
{
int num;
int numnum;
}numbers;
int main(int argc, char ** argv)
{
numbers* n = (numbers*)malloc(sizeof(numbers));
n->num = 1;
n->numnum = 2;
free(n);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAXSIZE 64
typedef struct word {
char word[MAXSIZE];
int freq;
} Word;
int word_counter = 0;
size_t pointer_counter = 16;//Number of pointers that ensure
void readWords(char norm_word[MAXSIZE], Word ** array) {
int i = 0;
bool found = false;
Word *current_pointer = *array;
for (i=0; i<word_counter; i++) {
if(strcmp(norm_word, current_pointer->word) == 0){
found = true;
current_pointer->freq++;
break;
}
++current_pointer;
}
if(!found) {
if(pointer_counter == word_counter) {
pointer_counter *= 2;
*array = realloc(*array, sizeof(Word)*pointer_counter);
}
Word *new_pointer = *array + word_counter;
new_pointer->freq = 1;
strcpy(new_pointer->word, norm_word);
++word_counter;
}
}
int main(void){
Word *vocabulary = calloc(pointer_counter, sizeof(Word));
char norm_word[MAXSIZE];
while(1==scanf("%s", norm_word)){
readWords(norm_word, &vocabulary);
}
{
int i;
for(i = 0; i < word_counter; ++i){
printf("%s(%d)\n", vocabulary[i].word, vocabulary[i].freq);
}
}
free(vocabulary);
return 0;
}
I am trying to read in a text file, which contains integers, and place them into an array. I will be sorting them once I have the array created. However, I trying to make sure things work as I implement them but I am getting a segmentation fault when I attempt to open a file. I do not understand why.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE_T_MAX 16777216
/****** FORWARD DECLARATIONS ******/
void die(const char *message) {
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
// ARRAY
typedef struct int_array {
int *array;
size_t length;
size_t capacity;
} int_array;
void int_array_init(int_array *array);
void int_array_free(int_array *array);
void int_array_add(int_array *array, int value);
/****** END OF DECLARATIONS ******/
//
//
/********** MAIN PROGRAM **********/
int main(char argc, char *argv[]) {
// VARIABLES
FILE *data;
int_array numbers;
int_array_init(&numbers);
int i = 0;
char value[10];
// LOAD FILES
printf("Loading files...\n");
data = fopen("list0.txt", "r");
if(data == NULL) die("Failed to load file.");
while(!feof(data) && !ferror(data)) {
fscanf(data, "%s", value);
int_array_add(&numbers, atoi(value));
printf("%d", numbers.array[i]);
i++;
}
// CLEAN UP
int_array_free(&numbers);
fclose(data);
return 0;
}
/*********** END OF MAIN **********/
//
//
/******* ADDITIONAL METHODS *******/
void int_array_init(int_array *array) {
array->array = NULL;
array->length = 0;
array->capacity = 0;
}
void int_array_free(int_array *array) {
free(array->array);
array->array = NULL;
array->length = 0;
array->capacity = 0;
}
void int_array_add(int_array *array, int value) {
if (array->length == array-> capacity)
{
int new_capacity;
if (array->capacity == 0) new_capacity = 10;
else new_capacity = array->capacity * 2;
if (new_capacity > array->capacity && new_capacity < SIZE_T_MAX / sizeof(int)) {
int *new_array = realloc(array->array, new_capacity * sizeof(int));
if (new_array != NULL) {
array->array = new_array;
array->capacity = new_capacity;
} else {
die("Out of Memory");
}
} else {
die("Overflow.");
}
}
array->array[array->length] = value;
array->length++;
}
I have corrected and fixed my code. The problem was in the while loop being infinite and corrected with:
while(!feof(data) && !ferror(data))
Can anyone give me some indication as to why array of structs doesn't print out properly ?
I think its something to do with the memory I have allocated to the struct I am unsure !!
Using mac osx mountain lion xcode 4 gcc
Thanks for any help completely stuck!!
(Please have patience I am only a student !)
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
typedef struct{
char* one;
char* two;
} Node;
Node *nodes;
int count = 0;
//-----------------------------------------------------------------------
void add(char *one,char*two){
char x[40];
char y[40];
printf("reached..\n");
strcpy(x,one);
strcpy(y,two);
printf("--> X: %s\n",x);
printf("--> Y: %s\n",y);
Node newNode;
newNode.one = x;
newNode.two = y;
nodes[count]= newNode;
count++;
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void print(){
int x;
for (x = 0; x < 10; x++)
{
printf("%d : (%s, %s) \n",x,nodes[x].one, nodes[x].two);
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void check(char **arg)
{
if(strcmp(*arg, "Add") == 0)
{
add(arg[1],arg[2]);
}else if(strcmp(*arg,"print") == 0)
{
print();
}else{
printf("Error syntax Enter either: \n Add [item1][item2]\n OR \n print\n");
}
}
//-----------------------------------------------------------------------
void readandParseInput(char *line,char **arg)
{
if (fgets (line, 512, stdin)!= NULL) {
char * pch;
pch = strtok (line," \n\t");
int count = 0;
arg[0] = pch;
while (pch != NULL)
{
count++;
pch = strtok (NULL, " \n\t");
arg[count] =pch;
}
}else{
printf("\n");
exit(0);
}
}
//-----------------------------------------------------------------------
int main()
{
int size = 100;
nodes = calloc(size, sizeof(Node));
int i;
for(i = 0;i <100; i++){
printf("%s , %s \n",nodes[i].one,nodes[i].two );
// nodes[i].one = ".";
// nodes[i].two = ".";
}
char line[512]; /* the input line */
char *arg[50]; /* the command line argument */
while (1)
{
readandParseInput(line,arg);
if(arg[0] != NULL){
check(arg);
}
}
return(0);
}
You're keeping pointers to the following automatic variables:
char x[40];
char y[40];
These go out of scope when add() returns, leaving you with dangling pointers.
You either have to turn Node::one and Node::two into arrays, or allocate memory for them on the heap.
In you add() function, you cannot assign one struct to another via an = operator... you would have to copy it...
memcpy( &nodes[count], &newNode )
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *fn;
}NAME;
#define NAME_LEN 20
int main()
{
NAME name;
name.fn = (char *) calloc(NAME_LEN, sizeof(char));
strcpy(name.fn, "Namco");
printf("Name: %s\n", name.fn);
free(name.fn);
return 0;
}
you can't just assign a string like this in c
newNode.one = x;
newNode.two = y;
what is newNode.one referring to???
at Function add
newNode.one = x;
newNode.two = y;
to
newNode.one = strdup(x);
newNode.two = strdup(y);