2013-09-21 149 views
2

我正在处理Uni任务,并且遇到了问题。我试图使用for-loop在结构中的某个点处存储字符串输入。稍后,我打算使用指向数据存储位置的指针来获取字符串。现在的问题是,当我在for循环内移动时,点的地址也会改变。此代码:未指定C指针地址更改

printf("B: %p\n", txt->point); 
for(i = 0; i < input_sz; i++) 
{ 
    txt->point[i] = input[i]; 
} 
printf("A: %p\n", txt->point); 

给出的输出:

B: 0x7fc111803200 
A: 0x7fc111803265 

其中B是前值和A被复制后的值。

任何帮助调试这将非常感激!


编辑:这里的一些代码:

的结构:

struct text_storage { 
    char* start; 
    char* point; 
    char* end; 
} typedef text_t; 

初始化函数:

text_t* text_init(void *memory, size_t size) 
{ 
    text_t* to_return; 
    if(size < sizeof(text_t)) 
    { 
     return NULL; 
    } 
    to_return = (text_t*) memory; 
    to_return->start = to_return; 

    to_return->end = to_return->start + size; 
    to_return->point = to_return->start; 

    printf("Start: %p, point: %p, end: %p, end-start: %d\n", to_return->start, to_return->point, to_return->end, (to_return->end - to_return->start)); 


    return to_return; 
} 

文本存储方法中发生错误:

int text_store_entry(text_t *txt, const char *input, size_t input_sz) 
{ 
    int to_return; 
    char* begin = txt->point; 
    int i; 

    if(input_sz > (txt->end - txt->point)) 
    { 
     return -1; 
    } 

    printf("Start: %p, point: %p, end: %p, end-start: %d\n", txt->start, txt->point, txt->end, (txt->end - txt->start)); 


    printf("B: %p\n", txt->point); 
    for(i = 0; i < input_sz; i++) 
    { 
     txt->point[i] = input[i]; 
    } 
    printf("A: %p\n", txt->point); 

} 

主要功能(测试目的只):

int main(int argc, char* argv[]) 
{ 
    void* memory = malloc(10000); 
    char* a = "hei pa deg din trekkbasun"; 
    text_t* txt; 
    int memoverwritten; 

    txt = text_init(memory, 10000); 

    memoverwritten = text_store_entry(txt, a, (size_t)26); 


    printf("got through\n"); 
    return 0; 
} 
+3

显示声明和其他代码。 - 可能未定义的行为 –

+0

现在添加了更多代码。谢谢@GrijeshChauhan –

+0

但我看不到你在哪里调用'text_store_entry()'函数? –

回答

3

问题最可能是由于struct text_storage类型的结构的初始化。这样的结构包含三个文本指针。应该初始化每个指针,可能带有malloc。你的text_init函数没有做到这一点。 实际上,存储指针的地方与要使用的内存的第一个字节重叠。

我猜,你需要这样的结构:

typedef struct text_storage { 
    char* start; 
    char* point; 
    char* end; 
    char* data; 
} text_t; 

具有这样的功能初始化:

text_t text_init(void *memory, size_t size) 
{ 
    text_t to_return; 
    to_return.data = (char *) memory; 
    to_return.start = to_return.data; 
    to_return.end = to_return.start + size; 
    to_return.point = to_return.start; 
    return to_return; 
} 
+0

赋值指定我们允许使用的唯一堆空间是传递给text_init函数的空间。我们不允许在该块之外预留堆内存。这让我没有malloc恐怕:( –

+0

好吧,没有'malloc',见上面。如果你想用'memory'来存储完整的结构,你需要一个带有最后一个可变大小字段的结构,看到[这里](http://stackoverflow.com/questions/7641698/allocating-struct-with-variable-length-array-member)。 – nickie

+0

谢谢!所以你使用另一个数据指针?你怎么看关于将开始和结束指针改为空长数组?然后它们将占用0个字节并且只指向内存中的某个地方,对吗? –

0

打印txt->在循环点,看到点它改变了。我猜它分配给txt-> point [0]时会改变。我对printf并不完全熟悉,所以我不确定它会为您打印什么,但数组的名称引用了第一个位置。如果printf打印出一个指针,那么txt-> point [i]总是一个char指针,printf可能会取消引用txt-> point,这会将其作为第一个条目,然后在那里显示地址,当你改变点输入[我]。

+0

这似乎是正确的。当它进入第一次迭代时,点的地址更改为新值(从开始起为+65),并在整个循环中保持该值。当在循环内打印txt-> point [i]的地址时,我可以看到它每次迭代移动4个字节。这是有道理的,因为我们正在存储字符。 –

+0

在这种情况下,将您的printf语句更改为打印&txt-> point [0],并希望它保持不变,向您显示您的数组没有移动。虽然我不会期望printf在每次迭代时改变,正如你所说的那样,所以让我想知道。 –

+0

这样的调试没有必要,问题很明显。在初始化结构的方式中,'txt','&(txt-> start)'和'txt-> start'都指向相同的地址('memory')。当你开始添加文本时,你会删除'txt-> start'的值。 – nickie