|
|
View previous topic :: View next topic |
Author |
Message |
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
Pointer problem |
Posted: Sun Mar 11, 2007 5:08 am |
|
|
I have wasted hours trying to solve an annoying problem with pointers that previously did not appear in my program. I noticed it when my program got bigger (85% of an 18F452). Compiler is 3.249.
I have this piece of code: Code: |
struct str_input_s {
char *ptr; // Pointer to the source/destionation variable
char s[UNIT_CHARS+1]; // String for char entering, UNIT_CHARS max!!
int8 len; // String length
int8 i; // Current char being modified
int8 menu_id; // Menu in which the variable is in
int8 menu_s; // The variable's position in the menu
} strinput;
void init_input_string(char *ptr, int8 len, int8 menu_id, int8 menu_s) {
strinput.ptr = ptr;
strncpy(strinput.s, ptr, UNIT_CHARS+1);
printf("ptr=%ld\r\n", ptr);
...
} |
Here is the call to this function: Code: | printf("param_ptr=%ld\r\n", menu.param_ptr[menu.s]);
init_input_string(menu.param_ptr[menu.s], UNIT_CHARS, // Pointer, len
menu.id, menu.s); // menu_id, menu_s
...
} |
menu.param_ptr is an array of void pointers and that location correctly prints out to be 148, but when I print ptr inside the init function, this one is 0. What am I doing wrong? This code worked ok before. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 11, 2007 12:40 pm |
|
|
Can you post a test program ? Then I can work on it.
It doesn't have to be long. Just the code that you posted,
plus all missing declarations. Just so it will compile. |
|
|
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
|
Posted: Sun Mar 11, 2007 1:32 pm |
|
|
I hate when it happens like this, the test program below works as expected.
Code: | #define CLKSPEED 40000000
#include <18F452.h>
#fuses H4,NOPROTECT,WDT,NODEBUG,NOLVP
#use delay(clock=CLKSPEED)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, enable=PIN_C5, parity=N, bits=8, restart_wdt, errors)
#include <string.h>
#zero_ram
#define UNIT_CHARS 5
#define OPT_MAX 13
// Data for a menu
struct menu_s {
int8 id; // Current menu id
signed int8 s; // Current selected option
int8 length; // Number of options
void* param_ptr[OPT_MAX]; // Pointers to the source data
} menu;
// Data for the string input task
struct str_input_s {
char *ptr; // Pointer to the source/destionation variable
char s[UNIT_CHARS+1]; // String for char entering, UNIT_CHARS max!!
int8 len; // String length
int8 i; // Current char being modified
int8 menu_id; // Menu in which the variable is in
int8 menu_s; // The variable's position in the menu
} strinput;
void init_input_string(char *ptr, int8 len, int8 menu_id, int8 menu_s) {
strinput.ptr = ptr;
/**/printf("ptr=%ld\r\n", ptr);
strncpy(strinput.s, ptr, UNIT_CHARS+1);
/**/puts(strinput.s);
/**/puts(ptr);
strinput.i = 0;
strinput.len = len;
strinput.menu_id = menu_id;
strinput.menu_s = menu_s;
}
struct {
char str[3][6];
} test;
void main() {
// Disable everything by default
setup_low_volt_detect(FALSE);
setup_oscillator(OSC_NORMAL);
setup_adc(ADC_OFF);
setup_adc_ports(NO_ANALOGS);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_DISABLED | T1_DIV_BY_1);
setup_timer_2(T2_DISABLED, 255, 1);
setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
// 7 6 5 4 3 2 1 0
set_tris_a(0b11010000); // x x LED1 DOUT DIN CLK CS_DAC CS_ADC
set_tris_b(0b11110000); // PGD PGC PGM x REL4 REL3 REL2 REL1
set_tris_c(0b10011111); // RX TX RE_DE x KEY4 KEY3 KEY2 KEY1
set_tris_d(0b11111111); // LCD_D7 LCD_D6 LCD_D5 LCD_D4 LCD_L LCD_EN LCD_RW LCD_RS
set_tris_e(0b11111000); // x x x x x LED4 LED3 LED2
delay_ms(500);
strcpy(test.str[0], "aaaaa");
strcpy(test.str[1], "bbbbb");
strcpy(test.str[2], "ccccc");
menu.id = 0;
menu.s = 0;
menu.length = 3;
menu.param_ptr[0] = test.str[0];
menu.param_ptr[1] = test.str[1];
menu.param_ptr[2] = test.str[2];
/**/printf("param_ptr=%ld\r\n", menu.param_ptr[menu.s]);
init_input_string(menu.param_ptr[menu.s], UNIT_CHARS, menu.id, menu.s);
while(1) restart_wdt();
} |
This prints: Code: | param_ptr=49
ptr=49
aaaaa
aaaaa |
which is ok. In the main program ptr would have been 0.
I also noticed similar problems with float parameters passed by refference to a function. That float was zero in the function. I removed the & and the problem was solved. Of course, this appeared after my program grew in size
Can't this compiler be safely used with programs bigger than average? It is getting very annoying trying to find workarounds for the bugs in the compiler. |
|
|
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
|
Posted: Sun Mar 11, 2007 5:08 pm |
|
|
It seems to me that when dealing with large programs, the compiler fails to evaluate some function parameters. I fixed my problem replacing this:
Code: | init_input_string(menu.param_ptr[menu.s], UNIT_CHARS, menu.id, menu.s); |
with this:
Code: | void *ptr;
...
ptr = menu.param_ptr[menu.s];
init_input_string(ptr, UNIT_CHARS, menu.id, menu.s); |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|