c - 为什么在windows下可以,但在linux下就不行呢?

标签 c linux

我的代码如下。

当我使用Visual Studio编译、调试和执行时,是正确的。而且我用gcc编译的时候也是对的,但是在Linux下执行就错了。运行时内存出错。

打印'szBuf'时,错误是无法访问内存。

我想知道为什么在Windows下可以工作,但在Linux下就不行?

#include <stdio.h>

void ItoA(int nNum, char *pStr);
void Print(const char *pFormat, ...);

int main()
{
    char  ch = 'a';
    int nNum = 11;
    char szBuf[255] = "";

    Print("ch: %c\n", ch);
    Print("n: %d\n", nNum);
    Print("s: %s\n", szBuf);

    return 0;
}

void ItoA(int nNum, char *pStr)
{
    if (NULL != pStr)
    {
        char szNum[255] = "";
        int i = 0;

        for (i = 0; 0 != nNum; i++)
        {
            szNum[i] = nNum % 10 + '0';
            nNum /= 10;
        }

        for (i = i - 1; i >= 0; i--, pStr++)
        {
            *pStr = szNum[i];
        }
        *pStr = '\0';
    }
}

void Print(const char *pFormat, ...)
{
    if (NULL != pFormat)
    {
        char *pTemp = (char *)&pFormat;
        pTemp += 4;

        while ('\0' != *pFormat)
        {
            if ('%' == *pFormat)
            {
                pFormat++;
                switch (*pFormat)
                {
                case 'c':
                {
                    putchar(*pTemp);
                    pTemp += 4;
                }
                break;
                case 'd':
                {
                    char szBuf[255] = "";
                    int nNum = 0;

                    ItoA(*(int *)pTemp, szBuf);

                    for (int i = 0; '\0' != szBuf[i]; i++)
                    {
                        putchar(szBuf[i]);
                    }

                    pTemp += 4;
                }
                break;
                case 's':
                {
                    for (int i = 0; '\0' != (*(char **)pTemp)[i]; i++)
                    {
                        putchar((*(char **)pTemp)[i]);
                    }

                    pTemp += 4;
                }
                break;
                default:
                {
                    pFormat--;
                    putchar(*pTemp);
                }
                break;
                }
            }
            else
            {
                putchar(*pFormat);
            }
            pFormat++;
        }
    }
}

最佳答案

这些行和 pTemp 周围的所有内容都有未定义的行为:

    char *pTemp = (char *)&pFormat;
    pTemp += 4;

您必须使用 stdarg.h 中的 va_startva_arg 来获取可变参数。 &pFormatPrint 函数中局部变量的地址,与参数的传递方式无关。对指向一个对象的指针进行算术不能产生指向另一对象的指针。

关于c - 为什么在windows下可以,但在linux下就不行呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58786268/

相关文章:

linux - 简单的基本 Flask 应用程序中的权限错误权限被拒绝

linux - 如何在文本/模式的前两个实例之间获取单词?

c - 为什么在 C 中使用错误的格式说明符会使我的程序在 Windows 7 上崩溃?

linux - GTK 中的阿拉伯语本地化

c++ - 如何全局捕获 X11 中的每一次鼠标点击?

c - 当我尝试从二进制文件中读取数组时,它没有出现在我的文本文件中

regex - 正则表达式与egrep

c - 程序的奇怪响应

c++ - 在macOS Catalina上编译Intel MKL CBLAS示例文件的问题

c - 对寻找循环列表算法的疑惑