2017-09-01 115 views
0

我有以下程序:(功能:垫空格串的右侧,使用astreix这里直观方便):为什么memset不按预期工作?

操作系统:Windows(视觉工作室)

#include "stdafx.h" 
#include<stdlib.h> 
#include<string.h> 

#define CBUFFSIZE 48 

void right_pad_str(char *pad_str, char *buff,int max_buffsize){ 

    int padstr_len = 0; 
    int space_len = 0; 
    char *end_str = NULL; 

    memset(buff, '\0', max_buffsize); 
    padstr_len = strlen(pad_str); 
    space_len = ((max_buffsize - 1) - padstr_len); 

    strncpy_s(buff, max_buffsize, pad_str, strlen(pad_str)); 

    end_str = buff +padstr_len; 

    memset((end_str), '*', space_len); 

    buff[max_buffsize] = '\0'; 

} 

int _tmain(int argc, _TCHAR* argv[]){ 
    char tmpstr[49] = { '\0' }; 
    char *str = "hello_world"; 

    right_pad_str(str, tmpstr, CBUFFSIZE + 1); 

    return 0; 
} 

好像有memset中的一个问题,当我看着memeset后的值,它看起来很不正确,即垃圾为什么会这样呢?最后我终止了字符串,但是我看到了垃圾值和堆栈损坏错误,不知道我的逻辑有什么问题。

(I附上相同的快照)

memset invalid value

+3

“最后我终止了字符串”您的屏幕截图显示终止字符串的行尚未执行。 – tkausl

+0

我null终止它为了增加安全性我memset它的权利在一开始,但我看到垃圾字符串 –

+1

是的,但字符串不是null终止。这将是一行之后。 –

回答

3

的意外的行为可以看出,在这个简单的例子:

#include <stdio.h> 
#include <string.h> 

int main(int argc, char **argv) 
{ 
    char buffer[3]; 
    buffer[0] = '\0'; 
    buffer[1] = '\0'; 
    buffer[2] = '\0'; 
    strncpy_s(buffer, 3, "*", 1); 
    printf("%u\n", (unsigned int)(unsigned char)buffer[2]); 
    return 0; 
} 

的输出是254,而不是0,但只在调试版本中。在调用strncpy_s期间发生这种情况,这意外地写入目标缓冲区,超过了副本的末尾,可能是为了暴露代码中的错误(已经指出)。


NB:退休忍者相当正确地指出(在评论的问题),这是描述不精确略在the documentation's印刷精美,我想最初忽视:

这些函数的调试版本首先用0xFD填充缓冲区。要禁用此行为,请使用_CrtSetDebugFillThreshold。

(事实上,在Visual Studio 2010中,至少,它填补与0xFE的缓冲区。)

+0

254与0xFD有什么关系?看起来像是一个偏离1的情况。 – chux

+1

@chux,我的猜测是文档中的一个错字。 –

2

@Harry Johnston精细答案解释什么地方出了错。


要垫的字符串其阵列尺寸,建议:

1)免除的'\0'memset(buff, ...);... strncpy_s(buff,...过度写入),它们随后用数据写入。

2)使用size_t作索引数组,字符串数学。 size_t是该作业的正确大小整数。

3)当出现很糟糕的形式调用时,比如使用长于目标的键盘或大小为0的调用。可能还会检查指针NULL

void right_pad_str(const char *pad_str, char *buff, size_t buff_size){ 
    if (buff_size > 0) { 
    size_t pad_size = strlen(pad_str) + 1; 
    if (pad_size > buff_size) { 
     pad_size = buff_size; 
    } 

    memcpy(buff, pad_str, pad_size - 1); 
    memset(&buff[pad_size - 1], '*', buff_size - pad_size); 
    buff[buff_size - 1] = '\0'; 
    } 
} 

// usage 
right_pad_str(str, tmpstr, sizeof tmpstr); 
相关问题