Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Access violation при использовании умного указат.


Автор: magesi 31.7.2012, 13:16
В чем проблема на линии obj->ip = "127.0.0.1"? Получаю violation, из-за чего именно в коде, будьте добры подсказать пожалуйста?

Код

typedef struct Header
{
    SOCKET sock;
    SOCKADDR_IN addr;
    WORD WSAVersion;
    WSAData data;
    char *ip;
    u_short port;
    int result;
} Header;

class A
{
private:
    std::unique_ptr<Header> obj;

public:
    A(void)
    {
        obj(new Header);
        obj->ip = "127.0.0.1"; // тут проблема
    }

    ~A(void)
    {
        obj.release();
    }
};

int main(void)
{
    std::unique_ptr<A> handler(new A);

Автор: boostcoder 31.7.2012, 13:37
Цитата(magesi @  31.7.2012,  13:16 Найти цитируемый пост)
obj(new Header);

что означает это выражение? оО
вроде должно быть так:
Код

obj.reset(new Header);

Автор: baldina 31.7.2012, 13:38
ну, он не настолько умный, что бы выделить память для 
Код

char *ip;  
smile 
Код

new Header 
распределяет память для Header, но не выделяет место под строку, которая представлена указателем.
Код

obj->ip = "127.0.0.1";

присваивает указателю адрес временной строки. это вам не std::string.

Добавлено через 2 минуты и 41 секунду
Цитата(boostcoder @  31.7.2012,  13:37 Найти цитируемый пост)
что означает это выражение? оО

ну конечно, конструктор то не так вызываться должен...

Автор: boostcoder 31.7.2012, 13:56
Цитата(baldina @  31.7.2012,  13:38 Найти цитируемый пост)
код C++
1:
new Header 
распределяет память для Header, но не выделяет место под строку, которая представлена указателем.
код C++
1:
obj->ip = "127.0.0.1";

присваивает указателю адрес временной строки. это вам не std::string.

и что тут невалидного?

Добавлено через 1 минуту и 23 секунды
указателю присваивается другой адрес. под сам же указатель память выделяется, если правильно инициализировать obj

Автор: baldina 31.7.2012, 14:04
да, проблема не в указателе, а в том что память вообще не выделяется.
со строкой проблем нет, она не временная (да и доступа к ней в программе нет), я ступил.
она в немодифицируемую области, и во всех экземплярах одина и тот же адрес.

Автор: magesi 31.7.2012, 14:20
boostcoder, baldina, 

спасибо, сейчас исправил все, работает, код:

Код

#include <iostream>
#include <memory>
#include <WinSock2.h>

#pragma comment(lib, "Ws2_32.lib")

typedef struct Header
{
    SOCKET sock;
    SOCKADDR_IN addr;
    WORD WSAVersion;
    WSAData data;
    char *ip;
    u_short port;
    int result;
} Header;

class Connector
{
private:
    std::unique_ptr<Header> obj;

public:
    Connector(void)
    {
        obj.reset(new Header);

        obj->ip = "193.201.231.44";
        obj->port = 2775;
        obj->WSAVersion = 0x202;

        obj->addr.sin_family = AF_INET;
        obj->addr.sin_addr.s_addr = inet_addr(obj->ip);
        obj->addr.sin_port = htons(obj->port);

        this->MakeConnection(&obj);
    }

    ~Connector(void)
    {
        obj.release();
    }

    int MakeConnection(std::unique_ptr<Header> *pointer)
    {
        (*pointer)->result = WSAStartup((*pointer)->WSAVersion, &(*pointer)->data);

        if((*pointer)->result != NO_ERROR)
        {
            std::cout << "WSA failed to start with the error: " << std::endl << (*pointer)->result << std::endl;
            return 0;
        }
        else
        {
            std::cout << "WSA started successfully" << std::endl;

            (*pointer)->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

            if((*pointer)->sock == SOCKET_ERROR)
            {
                std::cout << "Failed to init new socket, with the error: " << WSAGetLastError() << std::endl;
                return 0;
            }
            else
            {
                (*pointer)->result = connect(obj->sock, (sockaddr*)&(*pointer)->addr, sizeof((*pointer)->addr));

                if((*pointer)->result == SOCKET_ERROR)
                {
                    std::cout << "Failed to connect to the remote host " << (*pointer)->ip << ":" << (*pointer)->port
                        << ", with the error: " << WSAGetLastError() << std::endl;

                    return 0;
                }
                else
                {
                    std::cout << "Connected to the remote host " << (*pointer)->ip << ":" << (*pointer)->port << std::endl;

                    return 1;
                }
            }
        }
    }
};

void init(void)
{
    std::unique_ptr<Connector> obj;

    obj.reset(new Connector);
    obj.release();
}

int main(void)
{
    init();

    return 0;
}

Автор: boostcoder 31.7.2012, 14:25
Цитата(magesi @  31.7.2012,  14:20 Найти цитируемый пост)
WSAStartup

Цитата(magesi @  31.7.2012,  14:20 Найти цитируемый пост)
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

Цитата(magesi @  31.7.2012,  14:20 Найти цитируемый пост)
connect(obj->sock, (sockaddr*)&(*pointer)->addr, sizeof((*pointer)->addr));

ипитсо! писать на с++ и при этом использовать 'BSD sockets API' - это сила!

Автор: magesi 31.7.2012, 14:30
Цитата(boostcoder @ 31.7.2012,  14:25)
Цитата(magesi @  31.7.2012,  14:20 Найти цитируемый пост)
WSAStartup

Цитата(magesi @  31.7.2012,  14:20 Найти цитируемый пост)
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

Цитата(magesi @  31.7.2012,  14:20 Найти цитируемый пост)
connect(obj->sock, (sockaddr*)&(*pointer)->addr, sizeof((*pointer)->addr));

ипитсо! писать на с++ и при этом использовать 'BSD sockets API' - это сила!

Где ты там BSD sockets увидел? ) один WinSock только, что у BSD && WinSock есть одноименные ф-ции - ты же знаешь этот факт?  smile 

Цитата(boostcoder @  31.7.2012,  14:25 Найти цитируемый пост)
писать на с++ 

где я сказал, что это С++ ? может это pure C? smile

Цитата(boostcoder @  31.7.2012,  14:25 Найти цитируемый пост)
писать на с++ и при этом использовать 'BSD sockets API' 

А даже если бы я писал под *nix/cygwin на С++ с использованием BSD сокетов, и что дальше? ) теперь в честь как бы элегантности boost нужно его везде юзать, даже для ковырянии в сокетах?  smile надоели эти лишние либы, что есть в руках , то и юзай, в руки лопату bsd сокеты и работать  smile 

Автор: boostcoder 31.7.2012, 14:32
Цитата(magesi @  31.7.2012,  14:30 Найти цитируемый пост)
Где ты там BSD sockets увидел?

именно там. и называются они именно так. ибо BSD разработал этот API, а все остальные скопипастили.

Автор: magesi 31.7.2012, 14:34
Цитата(boostcoder @  31.7.2012,  14:32 Найти цитируемый пост)
именно там. и называются они именно так. ибо BSD разработал этот API, а все остальные скопипастили.

Точнее Berkley университет, когда еще зачатки для военки США в виде Апранета делали, но копипастить - нормально, а что есть другие вар-ты?  smile учитывая , что они сами сделали BSD лицензию на это, не shareware же  smile 

Ну с таким подходом мы далеко уйти может "используешь двоичную логику - переходи на факториальную систему исчисления" и тд, сам прекрасно понимаешь, что хоть и скопипастили, а ничего другого в Винде юзать не будешь  smile 

Автор: boostcoder 31.7.2012, 14:36
Цитата(magesi @  31.7.2012,  14:30 Найти цитируемый пост)
где я сказал, что это С++ ?

классы. шаблоны.

Автор: magesi 31.7.2012, 14:38
Цитата(boostcoder @  31.7.2012,  14:36 Найти цитируемый пост)
классы. шаблоны.

шаблоны есть и в С11 _Generic, а насчет множества под названием "класс" опустим глаза  smile 

ps
дык, я не понял, а что криминалого в симбиозе С++ && Berkley Sockets? а если бы я был под *nix и писал приложения там? что я должен по-твоему юзать?
boost не может , кстати разбирать саму структуру пакетов ( TCP или UDP это пакет ) если я захочу на низком уровне отслеживать всякие in-the-middle атаки или APR-спуффинга и многое другого

там есть несколько красивых рюшечек для асихноронной обработки и все оформлена в вызове одного метода, который все за тебя делает, а другого многое нет, ну еще можно отметить, что с бинарной сериализацией пакетов не надо возится, тоже удобно, но это и самому можно быстро

Автор: boostcoder 31.7.2012, 14:52
magesi, у меня небыло идеи развернуть холивар. так, провокация в надежде на ответ с юмором.

Автор: magesi 31.7.2012, 14:55
boostcoder, мне щя не до юмора )))) извиняй, вечером буду дома тебе перешлю фото, поймешь почему не до юмора ) у меня сейчас время такое, я юмор не понимаю  smile 

Автор: boostcoder 31.7.2012, 14:57
Цитата(magesi @  31.7.2012,  14:55 Найти цитируемый пост)
перешлю фото, поймешь почему не до юмора

уже страшно smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)