I was working on pop and push methods on the stack. Actually in this code I am creating dynamic array using pointers and malloc function. Then I was trying to add or delete elements to dynamic array with pop and push methods.But I getting the error in the question. I can't see any error in the code. Can you help me?
Here my main.c file
#include <stdio.h>
#include <stdlib.h>
#include "main_header.h"
stack * init(){
stack *s = (stack *) malloc(sizeof(stack));
s->items = NULL;
s->top = 0;
s->count = 2;
return s;
}
int pop(stack *s){
if(s->items == NULL){
printf("Items is empty.\n");
return -1;
}
if(s->top<=s->count/4){
int *items2 = (int *)malloc(sizeof(int)*s->count/2);
for (int i = 0; i < (s->count/2); i++){
items2[i] = s->items[i];
}
free(s->items); // burada "dizi" adındaki dizimiz dizi2 ile aynı yeri gösterdiğinde önceki 2 elemanlık dizi lost in space olacak bunu önlemek için free(dizi) diyerek o 2 elemanı bellekten siliyoruz.
s->items = items2;
s->count /= 2;
}
return s->items[--s->top];
}
void push(int a, stack *s){
if(s->items == NULL){
s->items = (int *)malloc(sizeof(int) * 2);
}
if(s->top>=s->count){
int *items2 = (int *)malloc(sizeof(int)*s->count*2);
for (int i = 0; i < s->count; i++)
items2[i] = s->items[i];
free(s->items); // burada "dizi" adındaki dizimiz dizi2 ile aynı yeri gösterdiğinde önceki 2 elemanlık dizi lost in space olacak bunu önlemek için free(dizi) diyerek o 2 elemanı bellekten siliyoruz.
s->items = items2;
s->count *= 2;
}
s->items[s->top++] = a;
}
void getItems(stack *s){
printf("count: %d\n", s->count);
for (int i = 0; i < s->top; i++) {
printf("%d\n", s->items[i]);
}
}
main_header.h file
#ifndef main
#define main
struct s {
int count;
int top;
int *items;
};
typedef struct s stack;
stack * init(void);
int pop(stack *);
void getItems(stack *);
void push(int, stack *);
#endif
test_stack.c file
#include <stdio.h>
#include <stdlib.h>
#include "main_header.h"
int main(){
stack *s1 = init();
stack *s2 = init();
for (int i = 0; i < 10; i++) {
push(i*10, s1);
}
getItems(s1);
for (int i = 0; i < 10; i++) {
push(pop(s1), s2);
}
return 0;
}
After #define main in “main_header.h”, the code int main(){ in “test_stack.c” is replaced by int (){. This causes the syntax error that the compiler (not Xcode) reports.
Do not use main in “main_header.h” as an indicator for whether the header file has been included already. Use some other name that you will not use for anything else, such as main_h or main_header_h.
(Clang is the compiler. Xcode is the overall integrated development environment that facilitates use of the compiler, organizes your projects files, opens editors, maintains your project options, and so on.)
Related
I'm trying to create a stack using a dynamic array and I'm getting an error when I try to run the DeleteStack() function, however, if I set a breakpoint before the function and run the main program up till that point, then continue past it, it executes properly. Would someone please tell me what I'm doing wrong and why I'm seeing this behavior?
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "dynamic_array_stack.h"
int main() {
// create stack
DynArrayStack *S = CreateStack();
// fill stack
for (int i = 1; i <= 10; i++)
Push(S, i);
// try pushing past capacity, no error (realloc's)
Push(S, 42);
// top of stack
printf("Top of stack is %d\n", Top(S));
// pop all elements of stack
while (Top(S) != INT_MIN) {
printf("%d\n", Pop(S));
}
// delete stack, check pointer again
DeleteStack(S);
return 0;
}
dynamic_array_stack.h:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct dynarraystack {
int top;
int capacity;
int *array;
} DynArrayStack;
DynArrayStack* CreateStack() {
DynArrayStack* S = malloc(sizeof(DynArrayStack));
if (!S) {
printf("Error: Could not create stack.\n");
return NULL;
}
S->capacity = 1;
S->top = -1;
S->array = malloc(S->capacity * sizeof(int));
if (!S->array) {
printf("Error: could not create stack.\n");
return NULL;
}
return S;
}
int isFullStack(DynArrayStack *S) {
return (S->top == S->capacity-1);
}
void DoubleStack(DynArrayStack *S) {
S->capacity *= 2;
S->array = realloc(S->array, S->capacity);
}
void Push(DynArrayStack *S, int data) {
if (isFullStack(S))
DoubleStack(S);
S->array[++S->top] = data;
}
int isEmptyStack(DynArrayStack *S) {
return S->top == -1;
}
int Top(DynArrayStack *S) {
if(isEmptyStack(S))
return INT_MIN;
return S->array[S->top];
}
int Pop(DynArrayStack *S) {
if (isEmptyStack(S)) {
printf("Array is empty. Returning INT_MIN.\n");
return INT_MIN;
}
return S->array[S->top--];
}
void DeleteStack(DynArrayStack *S) {
if (S) {
if (S->array)
free(S->array);
free(S);
printf("Stack deleted.\n");
}
}
edit: Actually it only does not error if I set two breakpoints, one before the while loop (so I step through it manually), and another before the DeleteStack() function. Still confused though.
Good afternoon! This is my first post here!
I have an invalid write error when I use valgrind, but when I can figure it when I use gdb!
#include <stdio.h>
#include <stdlib.h>
#define MAX_INDEX 2
void *z_m = 0;
struct block {
struct block * suiv;
};
//Declaration of a global array
struct block * tzl[MAX_INDEX+1];
//Function used to dislay tzl in the main.
void display() {
for(int i=0; i<=MAX_INDEX; i++) {
struct bloc * tmp = tzl[i];
printf("%d => ",i);
while (tmp!=NULL) {
printf(" %li ->",(unsigned long)tmp);
tmp = tmp -> suiv;
}
printf("\n");
}
}
int main() {
z_m = (void *) malloc(1<<MAX_INDEX);
for (int i=0; i<MAX_INDEX; i++)
{
tzl[i] = NULL;
}
tzl[MAX_INDEX] = z_m;
//Here is the problem with valgrind
tzl[MAX_INDEX] -> suiv = NULL;
display();
free(z_m);
return 0;
}
What can be the problem? Thank you for answering.
You are initializing tzl[2] with a pointer to a block of 4 bytes:
tzl[MAX_INDEX] = z_m; /* z_m is malloc(4) */
But you are then treating it as a pointer to struct block:
tzl[MAX_INDEX] -> suiv = NULL;
Declare z_m as struct block * and change malloc(1<<MAX_INDEX) to malloc(sizeof(struct block)) for a start.
You should also check to make sure malloc did not return NULL, and you should probably refrain from casting malloc's return value.
I'm having a problem that must be idiot, but I can't see why.
the main code reaches the "2test" print and then stops responding at l->n = 0;
This is my first (real) program in C, so my knowledge is small in this language.
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "list.h"
int main(){
TList* l;
FILE* txt = fopen("arqtxt.txt", "r");
char aux[80];
int c = fgetc(txt), x = 0;
printf("1test");
TList_Init(l);
printf("6test");
while ((c = fgetc(txt)) != EOF){
printf("%d",c);
while (!(isalpha(c))) c = fgetc(txt);
if (isupper(c)) c = c+32;
if (islower(c)) aux[x++] = (char) c;
else{
TList_Insert(l, aux);
strcpy(aux, "");
}
}
TList_Print(l);
getchar();
return 0;
}
list.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
void TList_Init (TList* l){
printf("2test");
l->n = 0;
printf("3test");
l->tam = 100;
printf("4test");
l->v = malloc(sizeof(TItem)*l->tam);
printf("5test");
}int TList_Search (TList* l, char* c){
int i;
for (i = l->n-1; i >= 0; i--)
if (strcmp(l->v[i].chave, c) == 0) return i;
return -1;
}
void InsertSort (TItem* v, int n){
int i,j;
TItem aux;
for (i = 1; i < n; i++){
aux = v[i];
j = i-1;
while (j >= 0 && strcmp(aux.chave, v[j].chave) < 0){
v[j+1] = v[j];
j--;
}
v[j+1] = aux;
}
}
void TList_Insert (TList* l, char word[80]){
if (l->n == l->tam){
l->tam += 100;
l->v = realloc(l->v, sizeof(TItem)*l->tam);
}
char* c = malloc(sizeof(char)*strlen(word));
c = word;
int aux = TList_Search(l, c);
if (aux != -1){
l->v[aux].no++;
return;
}
l->v[l->n].chave = c;
l->v[l->n].no = 1;
l->n++;
InsertSort(l->v, l->n);
}
void TList_Print (TList* l){
int x;
for (x = 0; x <= l->n; x++)
printf("%s - %d", l->v[x].chave, l->v[x].no);
}
list.h:
#ifndef LIST_H_
#define LIST_H_
typedef struct Item{
char* chave;
int no;
} TItem;
typedef struct List{
TItem* v;
int n, tam;
} TList;
void TList_Init (TList*);
void TList_Insert (TList*, char[]);
void TList_Print (TList*);
#endif
output:
||=== Build: Debug in EP1 (compiler: GNU GCC Compiler) ===|
C:\Users\Lucas\Desktop\EP1\main.c||In function 'main':|
C:\Users\Lucas\Desktop\EP1\main.c|13|warning: 'l' is used uninitialized in this function [-Wuninitialized]|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
||=== Run: Debug in EP1 (compiler: GNU GCC Compiler) ===|
-------------- Run: Debug in EP1 (compiler: GNU GCC Compiler)---------------
Checking for existence: C:\Users\Lucas\Desktop\EP1\bin\Debug\EP1.exe
Executing: "C:\Program Files (x86)\CodeBlocks/cb_console_runner.exe" "C:\Users\Lucas\Desktop\EP1\bin\Debug\EP1.exe" (in C:\Users\Lucas\Desktop\EP1\.)
Process terminated with status -1073741510 (0 minute(s), 9 second(s))
To expand on Jens' correct answer: TList* l; initialises a pointer to an address in memory - it does not allocate the memory for TList itself, so l most likely points to some random chunk of memory that you should not have access to.
You'd have to either call
l = malloc(sizeof(*l))
to reserve memory. Remember to call free(l); once you're done.
Alternatively declare l not as pointer, but rather as TList:
TList l;
[...]
TList_Init(&l);
This reserves memory in stack for TList, and passes a pointer via & to the method, with the proper memory allocated - in this case, you do not need to free the memory, as it's automagically freed once the method in which the variable was declared returns.
You never initialize the pointer l before you pass it to TList_Init(l);. Then assigning to l->n leads to undefined behavior in C language standardese because you use an indeterminate value.
What about making TList_Init() returning a ptr-to-TList instead?
TList *TList_Init (void)
{
TList *l;
l = malloc (sizeof *l);
/* Check l != NULL here ... omitted. */
printf("2test\n");
l->n = 0;
printf("3test\n");
l->tam = 100;
printf("4test\n");
l->v = malloc(sizeof(TItem) * l->tam);
printf("5test\n");
return l;
}
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 wonder if I'm doing something wrong in my program.
I manage to create a HashTable but when I send it through parameter to my displayingList() function, it crashes.
source.c (contains my functions):
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include "header.h"
#define MAX 255
int countLetters(char myStr[])
{
int myLen = strlen(myStr), i;
int wordLen = 0;
for (i = 0 ; i < myLen; ++i)
{
wordLen += (int)(myStr[i]);
}
return (wordLen%256);
}
void populateList(NodeT *T[255], char myStr[])
{
NodeT *p, *q;
p = (NodeT *)malloc(sizeof(NodeT));
strcpy (p->key, myStr);
int myPos = countLetters(myStr);
if(T[myPos] == NULL)
{
p->next = NULL;
T[myPos] = p;
}
else
{
q = T[myPos];
p->next = q;
T[myPos] = p;
}
}
void displayList(NodeT *T[255])
{
int i;
NodeT *p;
for(i = 0 ; i < 255; ++i)
{
if(T[i] != NULL)
{
printf("Index: %d - Data:", i);
p = T[i];
while(p != 0)
{
printf("%s, ", p->key); // HERE IT CRASHES.
p = p->next;
}
printf("\n");
}
}
}
main.c (contains the int main()):
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(void)
{
NodeT *T[255];
int n, i;
printf("Give no. of elements:");
scanf("%d", &n);
fflush(stdin);
for(i = 0 ; i < n ; ++i)
{
char name[100];
gets(name);
populateList(T, name);
}
displayList(T);
return 0;
}
header.h (and my header):
#ifndef HEADER_H
#define HEADER_H
typedef struct cell
{
char key[100];
struct cell *next;
}NodeT;
int countLetters(char myStr[]);
void populateList(NodeT *T[], char myStr[]);
void displayList(NodeT *T[]);
#endif // HEADER_H
I tried to see what exactly happens with debugger and it seems that when I send T[] list to displayList() function, actually it doesn't have the same structure as it has in main.c.
ISSUE: the insertion works fine, but when I try to display my list (on each index) it crashes.
Any ideas?
Thanks in advance.
The possible solution is to declare the NodeT *T[255] global. However it isn't the best practice at all.